<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>BeanIO 1.2 Reference Documentation</title>
<link rel="stylesheet" type="text/css" href="style.css" />
<link rel="shortcut icon" href="http://www.beanio.org/favicon.ico" />
</head>
<body>

<div class="title">BeanIO 1.2 - Reference Documentation</div>
<p><i>Revision 4</i>, &copy; 2010-2012 Kevin Seim</p>
<p style="font-size: 90%"><i>Copies of this document may be made for your own use and for
distribution to others, provided that you do not charge any fee for such copies and further provided
that each copy contains this Copyright Notice, whether distributed in print or electronically.</i></p>
<p style="font-size: 100%;"></p>
<h1>Table of Contents</h1>
<div class="toc">
<a href="#Introduction">1.0. Introduction</a><br />
<div class="toc">
  <a href="#WhatsNew">1.1. What's new in 1.2?</a><br />
 <a href="#Migration">1.2. Migrating From 1.1.x</a><br />
</div>
<a href="#GettingStarted">2.0. Getting Started</a><br />
<div class="toc"><a href="#MyFirstStream">2.1. My First Stream</a></div>
<a href="#CoreConcepts">3.0. Core Concepts</a><br />
<div class="toc">
  <a href="#BeanReader">3.1. BeanReader</a><br />
  <a href="#BeanWriter">3.2. BeanWriter</a><br />
  <a href="#MappingFiles">3.3. Mapping Files</a><br />
  <a href="#StreamFactory">3.4. StreamFactory</a><br />
  <a href="#ExceptionHandling">3.5. Exception Handling</a><br />
  <div class="toc">
  	<a href="#BeanReaderErrorHandler">3.5.1. BeanReaderErrorHandler</a><br />
  </div>
</div>
<a href="#TheMappingFile">4.0. The Mapping File</a>
<div class="toc">
  <a href="#StreamDefinition">4.1. Stream Definitions</a><br />
  <div class="toc">
  	<a href="#RecordReaderWriter">4.1.1. Record Reader and Writer</a><br />
  	<a href="#CSVStreamFormat">4.1.2. CSV Streams</a><br />
  	<a href="#DelimitedStreamFormat">4.1.3. Delimited Streams</a><br />
  	<a href="#FixedLengthStreamFormat">4.1.4. Fixed Length Streams</a><br />
    <a href="#XmlStreamFormat">4.1.5. XML Streams</a><br />
  </div>
  <a href="#RecordDefinition">4.2. Record Definitions</a><br />
  <div class="toc">
	<a href="#RecordIdentification">4.2.1. Record Identification</a><br />
	<a href="#RecordOrdering">4.2.2. Record Ordering</a><br />
	<a href="#RecordGrouping">4.2.3. Record Grouping</a><br />
  </div>
  <a href="#FieldDefinitions">4.3. Field Definitions</a><br />
  <div class="toc">
	<a href="#FieldTypeConversion">4.3.1. Field Type Conversion</a><br />
	<a href="#CustomTypeHandlers">4.3.2. Custom Type Handlers</a><br />
	<a href="#CollectionFields">4.3.3. Collection Type Fields</a><br />
	<a href="#FixedLengthFields">4.3.4. Fixed Length Fields</a><br />
  </div>
  <a href="#PropertyDefinitions">4.4. Property Definitions</a><br />
  <a href="#BeanDefinitions">4.5. Nested Bean Definitions</a><br />
  <div class="toc">
	<a href="#BeanCollections">4.5.1. Collection Type Beans</a><br />
  </div>
  <a href="#StreamValidation">4.6. Stream Validation</a><br />
  <div class="toc">
    <a href="#RecordValidation">4.6.1. Record Validation</a><br />
    <a href="#FieldValidation">4.6.2. Field Validation</a><br />
  </div>
  <a href="#Templates">4.7. Templates</a><br />
</div>
<a href="#MappingXmlStreams">5.0.  Mapping XML Streams</a><br />
<div class="toc">
  <a href="#XmlIntroduction">5.1.  Introduction</a><br />
  <div class="toc">
    <a href="#MyFirstXmlStream">5.1.1.  My First XML Stream</a><br />
    <a href="#XmlValidation">5.1.2.  A Note on XML Validation</a><br />
  </div>
  <a href="#XmlNames">5.2.  XML Names</a><br />
  <a href="#XmlNamespaces">5.3.  XML Namespaces</a><br />
  <a href="#XmlStreams">5.4.  Stream Definitions for XML</a><br />
  <a href="#XmlGroups">5.5.  Group Definitions for XML</a><br />
  <a href="#XmlRecords">5.6.  Record Definitions for XML</a><br />
  <a href="#XmlFields">5.7.  Field Definitions for XML</a><br />
  <div class="toc">
    <a href="#XmlTypeConversion">5.7.1.  Field Type Conversion</a><br />
    <a href="#NullFields">5.7.2.  Marshalling Null Fields</a><br />
  </div>
  <a href="#XmlBeans">5.8.  Bean Definitions for XML</a><br />
  <a href="#XmlWrappers">5.9.  XML Wrappers</a><br />
</div>
<a href="#SpringBatch">6.0. Spring Batch Integration</a>
<div class="toc">
  <a href="#SpringItemReaderWriter">6.1. BeanIO ItemReader/Writer Beans</a><br />
  <a href="#SpringStreamFactory">6.2. BeanIO StreamFactory Bean</a>
</div>
<a href="#Configuration">7.0. Configuration</a>
<div class="toc">
  <a href="#ConfigurationSettings">7.1. Settings</a>
</div>
<a href="#A">Appendix A: XML Mapping File Reference</a><br />
<div class="toc">
  <a href="#beanio">A.1. <tt>beanio</tt></a><br />
  <a href="#import">A.2. <tt>import</tt></a><br />
  <a href="#typeHandler">A.3. <tt>typeHandler</tt></a><br />
  <a href="#property">A.4. <tt>property</tt></a><br />
  <a href="#template">A.5. <tt>template</tt></a><br />
  <a href="#include">A.6. <tt>include</tt></a><br />
  <a href="#stream">A.7. <tt>stream</tt></a><br />
  <a href="#reader">A.8. <tt>reader</tt></a><br />
  <a href="#writer">A.9. <tt>writer</tt></a><br />
  <a href="#group">A.10. <tt>group</tt></a><br />
  <a href="#record">A.11. <tt>record</tt></a><br />
  <a href="#bean">A.12. <tt>bean</tt></a><br />
  <a href="#field">A.13. <tt>field</tt></a><br />
</div>
<a href="#B">Appendix B: Error Message Parameters</a><br />
</div>

<h1><a name="Introduction">1.0. Introduction</a></h1>
<p>BeanIO is an open source Java framework for reading and writing Java beans or plain old java
objects (POJO's) from a flat file or stream.  BeanIO is ideally suited for batch processing, and
currently supports XML, CSV, delimited and fixed length file formats. BeanIO is licensed under the <a
  href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0 License</a>.</p>

<h2><a name="WhatsNew">1.1. What's new in 1.2?</a></h2>
<p>BeanIO Release 1.2 includes the following enhancements and bug fixes:</p>
<ul>
  <li>Added ItemReader/ItemWriter support for <a href="#SpringBatch">Spring Batch 2.1</a>.</li>
  <li>Added support for mapping record/bean <a href="#property"><tt>property</tt></a> values that do
    not correspond to a field in the stream.  See <a href="#PropertyDefinitions">
    Section 4.4. Property Definitions</a>.</li>
  <li>Added support for skipping commented lines in CSV, delimited and fixed length streams.</li>
  <li>Added <a href="#import"><tt>import</tt></a> mapping file support.</li>
  <li>Added support for bean property templates</li>
  <li>Added support for assigning globally declared type handlers to a specific stream format.</li>
  <li>Relaxed bean introspection validation rules based on a <a href="#stream">stream</a> <tt>mode</tt> setting.</li>
  <li>Allow <a href="#property"><tt>property</tt></a> values to use the escape sequences <tt>\t</tt>, <tt>\n</tt>, 
    <tt>\r</tt>, <tt>\f</tt>, and <tt>\\</tt>.</li>
  <li>Fixed mapping validation rule to allow multiple record identifying fields.  
    (<a href="http://code.google.com/p/beanio/issues/detail?id=13">gc0013</a>)</li>
  <li>Modified XML unmarshalling to skip calling setter methods (with null) for missing elements and attributes.
    (<a href="http://code.google.com/p/beanio/issues/detail?id=14">gc0014</a>)</li>
  <li>Added the constant <tt>TypeHandler.NIL</tt> to allow <tt>format()</tt> to instruct an XML writer to write
    a nil element even if <tt>minOccurs</tt> is set to 0.</li>
</ul>

<h2><a name="Migration">1.2. Migrating from 1.1.x</a></h2>
<p>Release 1.2 is functionally backwards compatible with 1.1.  The only feature that may require mapping
file changes is the added support for escaping <a href="#property"><tt>property</tt></a> values using 
a backslash (e.g. <tt>\n</tt> is now recognized as a line feed).  If necessary, you can disable this feature
by setting the configuration setting <tt>org.beanio.propertyEscapingEnabled</tt> to <tt>false.</tt>  For more
information, see <a href="#Configuration">Section 7.0. Configuration</a>.</p>
<p>Programatically, significant changes were made to <tt>org.beanio.config.ConfigurationLoader</tt> interface
and its implementation.  All other major interfaces are backwards compatible with release 1.1.</p>

<h1><a name="GettingStarted">2.0. Getting Started</a></h1>
<p>To get started with BeanIO, download the latest stable version from 
<a href="http://code.google.com/p/beanio/">Google Code</a>, extract the contents of the ZIP file, 
and add <tt>beanio.jar</tt> to your application's classpath.</p>

<p>BeanIO requires a version 1.5 JDK or higher.  In order to process XML formatted streams,
BeanIO also requires an XML parser based on the Streaming API for XML (StAX), as specified by 
<a href="http://www.jcp.org/en/jsr/detail?id=173">JSR 173</a>.  JDK 1.6 and higher includes
a StAX implementation and therefore does not require any additional libraries.  JDK 1.5 users
will need to include the following:</p>
<ul>
<li>The StAX/JSR 173 API JAR, available from <a href="http://sjsxp.java.net/">Project SJSXP</a>.</li>
<li>A StAX implementation JAR.  A reference implementation, used for BeanIO development and included
in JDK 1.6, is available from <a href="http://sjsxp.java.net/">Project SJSXP</a>.</li>
</ul>

<p>Alternatively, <a href="http://maven.apache.org/">Maven</a> users can declare the following dependencies
  in their application's POM.  Note that the version numbers documented below are only examples 
  and may have changed.</p>
<pre>
    &lt;!-- BeanIO dependency --&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.beanio&lt;/groupId&gt;
      &lt;artifactId&gt;beanio&lt;/artifactId&gt;
      &lt;version&gt;1.1.0&lt;/version&gt;
    &lt;/dependency&gt;

    &lt;!-- StAX dependencies for JDK 1.5 users --&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;javax.xml&lt;/groupId&gt;
      &lt;artifactId&gt;jsr173&lt;/artifactId&gt;
      &lt;version&gt;1.0&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;com.sun.xml.stream&lt;/groupId&gt;
      &lt;artifactId&gt;sjsxp&lt;/artifactId&gt;
      &lt;version&gt;1.0.1&lt;/version&gt;
    &lt;/dependency&gt;
</pre>

<h2><a name="MyFirstStream">2.1. My First Stream</a></h2>
<p>This section explores a simple example that uses BeanIO to read and write
a flat file containing employee data.  Let's suppose the file is in CSV format
and has the following record layout: </p>

<div class="indent">
  <table>
    <tr><th>Position</th><th>Field</th><th>Format</th></tr>
    <tr><td>0</td><td>First Name</td><td>Text</td></tr>
    <tr><td>1</td><td>Last Name</td><td>Text</td></tr>
    <tr><td>2</td><td>Job Title</td><td>Text</td></tr>
    <tr><td>3</td><td>Salary</td><td>Number</td></tr>
    <tr><td>4</td><td>Hire Date</td><td>Date (MMDDYYYY)</td></tr>
  </table>
</div>

<p>A sample file is shown below.</p>
<pre class="file">
Joe,Smith,Developer,75000,10012009
Jane,Doe,Architect,80000,01152008
Jon,Anderson,Manager,85000,03182007</pre>

<p>Next, let's suppose we want to read records into the following Java bean for further processing.
Remember that a Java bean must have a default no-argument constructor and public getters and setters
for all exposed properties.</p>
<pre class="java">
package org.beanio.example;
import java.util.Date;

public class Employee {
    String firstName;
    String lastName;
    String title;
    int salary;
    Date hireDate;
    
    <span class="comment">// getters and setters not shown...</span>
}</pre>

<p>BeanIO uses an XML configuration file, called a mapping file, to define how bean objects are bound
to records.  Below is a mapping file, named <tt>mapping.xml</tt>, that could be
used to read the sample employee file and unmarshall records into <tt>Employee</tt> objects.  The
same mapping file can be used to write, or marshall, <tt>Employee</tt> objects to a file
or output stream.</p>
<pre class="file">
&lt;beanio xmlns="http://www.beanio.org/2011/01" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.beanio.org/2011/01 http://www.beanio.org/2011/01/mapping.xsd"&gt;

  &lt;stream name="employeeFile" format="csv"&gt;
    &lt;record name="employee" class="org.beanio.example.Employee"&gt;
      &lt;field name="firstName" /&gt;
      &lt;field name="lastName" /&gt;
      &lt;field name="title" /&gt;
      &lt;field name="salary" /&gt;
      &lt;field name="hireDate" format="MMddyyyy" /&gt;
    &lt;/record&gt;
  &lt;/stream&gt;
&lt;/beanio&gt;</pre>

<p>To read the employee CSV file, a <tt>StreamFactory</tt> is used to load our mapping
file and create a <tt>BeanReader</tt>, which is used to unmarshall <tt>Employee</tt>
objects from the file <tt>employee.csv</tt>.  (For the sake of brevity, proper exception handling 
is not shown.)</p>
<pre class="java">
package org.beanio.example;

import org.beanio.*;
import java.io.*;

public class BeanReaderExample {
    public static void main(String[] args) throws Exception {
        <span class="comment">// create a StreamFactory</span>
        StreamFactory factory = StreamFactory.newInstance();
        <span class="comment">// load the mapping file</span>
        factory.load("mapping.xml");
        
        <span class="comment">// use a StreamFactory to create a BeanReader</span>
        BeanReader in = factory.createReader("employeeFile", new File("employee.csv"));
        Employee employee;
        while ((employee = (Employee) in.read()) != null) {
            <span class="comment">// process the employee...</span>
        }
        in.close();
    }
}</pre>

<p>To write an employee CSV file, the same <tt>StreamFactory</tt> class
is used to create a <tt>BeanWriter</tt> for marshalling <tt>Employee</tt> bean objects to
the file <tt>employee.csv</tt>.  In this example, the same mapping configuration file is used for
both reading and writing an employee file.</p>
<pre class="java">
package org.beanio.example;

import org.beanio.*;
import java.io.*;
import java.util.*;

public class BeanWriterExample {
    public static void main(String[] args) throws Exception {
        <span class="comment">// create a StreamFactory</span>
        StreamFactory factory = StreamFactory.newInstance();
        <span class="comment">// load the mapping file</span>
        factory.load("mapping.xml");
        
        Employee employee = new Employee();
        employee.setFirstName("Jennifer");
        employee.setLastName("Jones");
        employee.setTitle("Marketing")
        employee.setSalary(60000);
        employee.setHireDate(new Date());
        
        <span class="comment">// use a StreamFactory to create a BeanWriter</span>
        BeanWriter out = factory.createWriter("employeeFile", new File("employee.csv"));
        <span class="comment">// write an Employee object directly to the BeanWriter</span>
        out.write(employee);
        out.flush();
        out.close();
    }
}</pre>

<p>Running <tt>BeanWriterExample</tt> produces the following CSV file.</p>
<pre class="file">
Jennifer,Jones,Marketing,60000,01012011</pre>

<h1><a name="CoreConcepts">3.0. Core Concepts</a></h1>

<h2><a name="BeanReader">3.1. BeanReader</a></h2>
<p>The <tt>BeanReader</tt> interface, shown below, is used to read bean objects from
an input stream.  The method <tt>read()</tt> returns the bean object for the next record
read from the input stream, or <tt>null</tt> when the end of the stream is reached.  
The method <tt>getRecordName()</tt> returns the name of the
last record read from the input stream, as named in the mapping file.  And  
<tt>getLineNumber()</tt> returns the line number of the last record from the input
stream.  The method <tt>setErrorHandler(...)</tt> can be used to register a custom error
handler.  If an error handler is not configured, <tt>read()</tt> simply throws the 
unhandled exception.</p>
<pre class="file">
package org.beanio;

public interface BeanReader {
    public Object read() throws BeanReaderException;
    
    public String getRecordName();
    
    public int getLineNumber();
    
    public int skip(int count) throws BeanReaderException;
    
    public void close() throws BeanReaderIOException;
    
    public void setErrorHandler(BeanReaderErrorHandler errorHandler);
}</pre>

<h2><a name="BeanWriter">3.2. BeanWriter</a></h2>
<p>The <tt>BeanWriter</tt> interface, shown below, is used to write bean objects to
an output stream.  Calling the <tt>write(Object)</tt> method marshalls a bean object to the 
output stream.  In some cases where multiple record types are not discernible by class type 
or record identifying fields, the <tt>write(String,Object)</tt> method can be used to 
explicitly name the record type to marshall. </p>
<pre class="file">
package org.beanio;

public interface BeanWriter {

    public void write(Object bean) throws BeanWriterException;
    
    public void write(String recordName, Object bean) throws BeanWriterException;
    
    public void flush() throws BeanWriterIOException;
    
    public void close() throws BeanWriterIOException;
}</pre>

<h2><a name="MappingFiles">3.3. Mapping Files</a></h2>
<p>BeanIO uses XML configuration files, called mapping files,
to bind a stream layout to Java objects.  Multiple layouts
can be configured in a single mapping file using <tt>stream</tt> elements, and 
each stream is assigned a unique name for referencing the layout.  In addition to
its name, every stream must declare its format using the <tt>format</tt> attribute.  
Supported stream formats include <tt>csv</tt>,
<tt>delimited</tt>, and <tt>fixedlength</tt>.  Mapping files
are further explored in the next section (<a href="#TheMappingFile">4.0. The Mapping File</a>).</p>
<pre class="file">
&lt;beanio xmlns="http://www.beanio.org/2011/01" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.beanio.org/2011/01 http://www.beanio.org/2011/01/mapping.xsd"&gt;

  &lt;stream name="stream1" format="csv"... &gt;
    &lt;!-- record layout... --&gt;
  &lt;/stream&gt;
  
  &lt;stream name="stream2" format="fixedlength"... &gt;
    &lt;!-- record layout... --&gt;
  &lt;/stream&gt;
    
&lt;/beanio&gt;</pre>

<h2><a name="StremFactory">3.4. StreamFactory</a></h2>
<p>A <tt>StreamFactory</tt> is used to load mapping files and 
create <tt>BeanReader</tt> and <tt>BeanWriter</tt> instances.  The following
code snippet shows how to instantiate a <tt>StreamFactory</tt>, load a mapping
file and create a <tt>BeanReader</tt> and <tt>BeanWriter</tt>.  The <tt>load(...)</tt>
method loads mapping files from the file system (relative to the current working 
directory), while the method <tt>loadResource(...)</tt> loads mapping files from
the classpath.</p>

<pre class="java">
<span class="comment">// create a StreamFactory</span>
StreamFactory factory = StreamFactory.newInstance();
<span class="comment">// load 'mapping-1.xml' from the current working directory</span>
factory.load("mapping-1.xml");
<span class="comment">// load 'mapping-2.xml' from the classpath</span>
factory.loadResource("mapping-2.xml");'

<span class="comment">// create a BeanReader to read from 'in.txt'</span>
Reader in = new BufferedReader(new FileReader("in.txt"));
BeanReader beanReader = factory.createBeanReader("streamName", in);

<span class="comment">// create a BeanWriter to write to 'out.txt'</span>
Writer out = new BufferedWriter(new FileWriter("out.txt"));
BeanWriter beanWriter = factory.createBeanReader("streamName", out);    
</pre>

<h2><a name="ExceptionHandling">3.5. Exception Handling</a></h2>
<p>All BeanIO exceptions extend from <tt>BeanIOException</tt>, which
extends from <tt>RuntimeException</tt> so that exceptions do not need
to be explicitly caught unless desired.  <tt>BeanReaderException</tt>
and <tt>BeanWriterException</tt> extend from <tt>BeanIOException</tt>
and may be thrown by a <tt>BeanReader</tt> or <tt>BeanWriter</tt>
respectively.  
</p>

<p>
A <tt>BeanReaderException</tt> is further broken down into
the following subclasses thrown by the <tt>read()</tt> method. 
</p>
<div class="indent">
<table>
<tr><th>Exception</th><th>Description</th></tr>
<tr>
  <td><tt>BeanReaderIOException</tt></td>
  <td>Thrown when the underlying input stream throws an <tt>IOException</tt>, or
    in a few other fatal error scenarios.</td>
</tr>
<tr>
  <td><tt>MalformedRecordException</tt></td>
  <td>Thrown when the underlying input stream is malformed based on the configured
    stream format, and therefore the next record could not be accurately read from the
    stream.  In many cases, further reads from the input stream will be unsuccessful.
  </td>
</tr>
<tr>
  <td><tt>UnidentifiedRecordException</tt></td>
  <td>Thrown when a record does not match any record definition configured in the 
    mapping file.  If the stream layout does not strictly enforce record
    sequencing, further reads from the input stream are likely to be successful.
  </td>
</tr>
<tr>
  <td><tt>UnexpectedRecordException</tt></td>
  <td>Thrown when a record is read out of order.  Once record sequencing is violated,
    further reads from the input stream are likely to be unsuccessful.
  </td>
</tr>
<tr>
  <td><tt>InvalidRecordException</tt></td>
  <td>Thrown when a record is matched, but the record is invalid for one of the following
    reasons:
    <ul>
      <li>A record level validation failed</li>
      <li>One or more field level validations failed</li>
      <li>Field type conversion failed</li>
    </ul>
    This exception has no effect on the state of the <tt>BeanReader</tt> and further reads 
    from the input stream can be safely performed.
  </td>
</tr>
</table>
</div>

<p>When a <tt>BeanReaderException</tt> is thrown, the current state of
the input stream and any field or record level error messages can be accessed by
calling <tt>exception.getContext()</tt>, which returns the following <tt>BeanReaderContext</tt>
interface.  Please refer to the API javadocs for method details.</p>

<pre class="java">
package org.beanio;

public interface BeanReaderContext {
    public int getRecordLineNumber();
    public String getRecordText();
    public String getRecordName();
    public boolean hasRecordErrors();
    public Collection&lt;String&gt; getRecordErrors();
    public String getFieldText(String fieldName);
    public String getFieldText(String fieldName, int index);
    public boolean hasFieldErrors();
    public Map&lt;String, Collection&lt;String&gt;&gt; getFieldErrors();
    public Collection&lt;String&gt; getFieldErrors(String fieldName);
}</pre>


<h3><a name="BeanReaderErrorHandler">3.5.1. BeanReaderErrorHandler</a></h3>
<p>If you need to handle an exception and continue processing, it may be simpler to register
a <tt>BeanReaderErrorHandler</tt> using the <tt>beanReader.setErrorHandler()</tt> method.  The
<tt>BeanReaderErrorHandler</tt> interface is shown below.  Any exception thrown by the error
handler will be rethrown by the <tt>BeanReader</tt>.</p>
<pre class="java">
package org.beanio;

public interface BeanReaderErrorHandler {
    public void handleError(BeanReaderException ex) throws Exception;
}</pre>

<p>The following example shows how invalid records could be written to a reject file by
registering an error handler extending <tt>BeanReaderErrorHandlerSupport</tt>,
a subclass of <tt>BeanReaderErrorHandler</tt>.  All other exceptions are left uncaught and
will bubble up to the calling method.</p>
<pre class="java">
    BeanReader input;
    BufferedWriter rejects;
    try {
        input.setErrorHandler(new BeanReaderErrorHandlerSupport() {
            public void invalidRecord(InvalidRecordException ex) throws Exception {
                rejects.write(ex.getContext().getRecordText());
                rejects.newLine();
            }
        });
        
        Object record = null;
        while ((record = input.read()) != null) {
            <span class="comment">// process a valid record</span>
        }
        
        rejects.flush();
    }
    finally {
        input.close();
        rejects.close();
    }
</pre>


<h1><a name="TheMappingFile">4.0. The Mapping File</a></h1>
<p>An XML mapping file is used to configure a stream layout.</p>
<h2><a name="StreamDefinition">4.1. Stream Definitions</a></h2>
<p>A typical mapping file contains one or more stream definitions.  A stream
definition must have a <tt>name</tt> and <tt>format</tt> attribute configured. The name of the 
stream is used to reference the layout when creating a <tt>BeanReader</tt> or 
<tt>BeanWriter</tt> instance using a <tt>StreamFactory</tt>.  And the format instructs
BeanIO how to interpret the stream.  Supported formats include <tt>xml</tt>, <tt>csv</tt>, 
<tt>delimited</tt> and <tt>fixedlength</tt>.  
</p> 
<pre class="file">
&lt;beanio xmlns="http://www.beanio.org/2011/01" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.beanio.org/2011/01 http://www.beanio.org/2011/01/mapping.xsd"&gt;

  &lt;stream name="stream1" format="csv"... &gt;
    &lt;!-- record layout... --&gt;
  &lt;/stream&gt;
  
  &lt;stream name="stream2" format="fixedlength"... &gt;
    &lt;!-- record layout... --&gt;
  &lt;/stream&gt;
    
&lt;/beanio&gt;</pre>

<h3><a name="RecordReaderWriter">4.1.1. RecordReader and RecordWriter</a></h3>
<p>Internally, BeanIO uses a <tt>RecordReader</tt> to read records from an input stream,
and a <tt>RecordWriter</tt> to write records to an output stream.</p>

<p>The <tt>RecordReader</tt> interface is shown below.  A record reader is responsible
for dividing a stream into records.  The actual Java representation of a record is dependent
on the format of the stream.  Delimited record readers (including CSV) parse an input stream into 
<tt>String</tt> array records, where each value in the array is a delimited field.  
And fixed length record readers simply parse an input stream into <tt>String</tt> records.</p>
<pre class="java">
package org.beanio.stream;

public interface RecordReader {
    public Object read() throws IOException, RecordIOException;
    public void close() throws IOException;
    public int getRecordLineNumber();
    public String getRecordText();
}
</pre>


<p>Similarly, the <tt>RecordWriter</tt> interface show below is used to write records to an 
output stream.  Once again, the Java representation of a record is dependent on the format
of the stream.  Delimited (and CSV) records use a <tt>String</tt> array, and fixed length
records simply use a <tt>String</tt>.</p>
<pre class="java">
package org.beanio.stream;

public interface RecordWriterFactory {
    public RecordWriter createWriter(Writer out) throws IllegalArgumentException;
}
</pre>

<p>A new <tt>RecordReader</tt> is created for each <tt>BeanReader</tt> using the
<tt>RecordReaderFactory</tt> interface shown below.</p>
<pre class="java">
package org.beanio.stream;

public interface RecordReaderFactory {
    public RecordReader createReader(Reader in) throws IllegalArgumentException;
}
</pre>

<p>And likewise, a new <tt>RecordWriter</tt> is created for each <tt>BeanWriter</tt> using the
<tt>RecordWriterFactory</tt> interface shown below.</p>
<pre class="java">
package org.beanio.stream;

public interface RecordWriterFactory {
    public RecordWriter createWriter(Writer out) throws IllegalArgumentException;
}
</pre>

<p>BeanIO includes default record readers and writers for XML, CSV, delimited and fixed length 
stream formats.  Default reader and writer settings can be overridden for any stream in
the mapping file using a <tt>reader</tt> or <tt>writer</tt> element.  Or if necessary,
you can even replace the default record reader or writer by setting the <tt>class</tt> attribute
to the fully qualified class name of the record reader or writer factory to use.  (Note that
custom record reader/writer implementations will not be supported for XML formatted streams
due to the tight coupling with the parser, although it is not prevented.)</p>

<p>In the example mapping file below, the default record reader's delimiter is changed to an astericks,
while the record writer implementation is completely replaced using the factory class
<tt>org.beanio.example.MyRecordWriterFactory</tt>.</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="employeeFile" format="delimited"&gt;
    <span class="highlight">&lt;reader&gt;
      &lt;property name="delimiter" value="*" /&gt;
    &lt;/reader&gt; </span>
    <span class="highlight">&lt;writer class="org.beanio.example.MyRecordWriterFactory" /&gt; </span>
    &lt;record name="employee" class="org.beanio.example.Employee"&gt;
      &lt;field name="firstName" /&gt;
      &lt;field name="lastName" /&gt;
      &lt;field name="title" /&gt;
      &lt;field name="salary" /&gt;
      &lt;field name="hireDate" format="MMddyyyy" /&gt;
    &lt;/record&gt; 
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>


<h3><a name="CSVStreamFormat">4.1.2. CSV Streams</a></h3>
<p>The default record reader and writer for CSV formatted streams is based on 
<a href="http://www.ietf.org/rfc/rfc4180.txt">RFC 4180</a> with one exception:
multi-line records are disabled (but this can be overridden).</p>

<p>The following properties can be used to customize the default CSV record reader
and record writer:</p>
<table class="indent">
<tr>
  <th>Property</th>
  <th>Type</th>
  <th>Description</th>
  <th>Reader?</th>
  <th>Writer?</th>
</tr>
<tr>
  <td><tt>delimiter</tt></td>
  <td>char</td>
  <td>The field delimiter.  Defaults to a comma.</td>
  <td>Yes</td>
  <td>Yes</td>
</tr>
<tr>
  <td><tt>quote</tt></td>
  <td>char</td>
  <td>The quotation mark character used to wrap fields containing a delimiter character, a
    quotation mark, or new lines.  Defaults to the double quotation mark, ".</td>
  <td>Yes</td>
  <td>Yes</td>
</tr>
<tr>
  <td><tt>escape</tt></td>
  <td>Character</td>
  <td>The character used to escape a quotation mark in a quoted field.  Defaults to the
    double quotation mark, ".</td>
  <td>Yes</td>
  <td>Yes</td>
</tr>
<tr>
  <td><tt>comments</tt></td>
  <td>String[]</td>
  <td>A comma separated list of values for identifying commented lines.  If a line read from an input
    stream begins with any of the configured values, the line is ignored.  A backslash may
    be used to escape a comma and itself.  All whitespace is preserved.
    <p>Enabling comments require the input reader passed to <tt>StreamFactory</tt> to support marking.
    Among others, <tt>BufferedReader</tt> and <tt>StringReader</tt> support marking.</p></td>
  <td>Yes</td>
  <td>No</td>
</tr>
<tr>
  <td><tt>multilineEnabled</tt></td>
  <td>boolean</td>
  <td>If set to <tt>true</tt>, quoted fields may contain new line characters.  Defaults to <tt>false</tt>.</td>
  <td>Yes</td>
  <td>No</td>
</tr>
<tr>
  <td><tt>whitespaceAllowed</tt></td>
  <td>boolean</td>
  <td>If set to <tt>true</tt>, whitespace is ignored and allowed before and after 
  quoted values.  For example, the following is allowed:
  <pre>
    Jennifer, "Jones" ,24</pre>
  Defaults to <tt>false</tt>.
  </td>
  <td>Yes</td>
  <td>No</td>
</tr>
<tr>
  <td><tt>unquotedQuotesAllowed</tt></td>
  <td>boolean</td>
  <td>If set to <tt>true</tt>, field text containing quotation marks do not need to 
    be quoted unless the field text starts with a quotation mark.  For example, the
    following is allowed:
    <pre>
    Jennifer,She said "OK"</pre>
    Defaults to <tt>false</tt>.
  </td>  
  <td>Yes</td>
  <td>No</td>
</tr>
<tr>
  <td><tt>recordTerminator</tt></td>
  <td>String</td>
  <td>The character used to signify the end of a record.  By default, any new line character
    (line feed (LF), carriage return (CR), or CRLF combination) is accepted when reading
    an input stream, and <tt>System.getProperty("line.separator")</tt> is used when writing
    to a stream.</td>
  <td>No</td>
  <td>Yes</td>
</tr>
<tr>
  <td><tt>alwaysQuote</tt></td>
  <td>boolean</td>
  <td>If set to <tt>true</tt>, field text is always quoted.  By default, a field is only quoted
  if it contains a delimeter, a quotation mark or new line characters.
  </td>
  <td>No</td>
  <td>Yes</td>
</tr>
</table>


<h3><a name="DelimitedStreamFormat">4.1.3.  Delimited Streams</a></h3>
<p>The default delimited record reader and writer can be customized using the following properties:</p>
<table class="indent">
<tr>
  <th>Property</th>
  <th>Type</th>
  <th>Description</th>
  <th>Reader?</th>
  <th>Writer?</th>
</tr>
<tr>
  <td><tt>delimiter</tt></td>
  <td>char</td>
  <td>The field delimiter.  Defaults to the tab character.</td>
  <td>Yes</td>
  <td>Yes</td>
</tr>
<tr>
  <td><tt>escape</tt></td>
  <td>Character</td>
  <td>The escape character allowed to escape a delimiter or itself.  By default, escaping
    is disabled.</td>
  <td>Yes</td>
  <td>Yes</td>
</tr>
<tr>
  <td><tt>lineContinuationCharacter</tt></td>
  <td>Character</td>
  <td>If this character is the last character before a new line or carriage return is read,
    the record will continue reading from the next line.  By default, line continuation
    is disabled.</td>
  <td>Yes</td>
  <td>No</td>
</tr>
<tr>
  <td><tt>recordTerminator</tt></td>
  <td>Character</td>
  <td>The character used to signify the end of a record.  By default, any new line character
    (line feed (LF), carriage return (CR), or CRLF combination) is accepted when reading
    an input stream, and <tt>System.getProperty("line.separator")</tt> is used when writing
    to a stream.</td>
  <td>Yes</td>
  <td>Yes</td>
</tr>
<tr>
  <td><tt>comments</tt></td>
  <td>String[]</td>
  <td>A comma separated list of values for identifying commented lines.  If a line read from an input
    stream begins with any of the configured values, the line is ignored.  A backslash may
    be used to escape a comma and itself.  All whitespace is preserved.
    <p>Enabling comments require the input reader passed to <tt>StreamFactory</tt> to support marking.
    Among others, <tt>BufferedReader</tt> and <tt>StringReader</tt> support marking.</p></td>
  <td>Yes</td>
  <td>No</td>
</tr>
</table>


<h3><a name="FixedLengthStreamFormat">4.1.4. Fixed Length Streams</a></h3>
<p>The default fixed length reader and writer can be customized using the following properties:</p>
<table class="indent">
<tr>
  <th>Property</th>
  <th>Type</th>
  <th>Description</th>
  <th>Reader?</th>
  <th>Writer?</th>
</tr>
<tr>
  <td><tt>lineContinuationCharacter</tt></td>
  <td>Character</td>
  <td>If this character is the last character before a new line or carriage return is read,
    the record will continue reading from the next line.  By default, line continuation
    is disabled.</td>
  <td>Yes</td>
  <td>No</td>
</tr>
<tr>
  <td><tt>recordTerminator</tt></td>
  <td>Character</td>
  <td>The character used to signify the end of a record.  By default, any new line character
    (line feed (LF), carriage return (CR), or CRLF combination) is accepted when reading
    an input stream, and <tt>System.getProperty("line.separator")</tt> is used when writing
    to a stream.</td>
  <td>Yes</td>
  <td>Yes</td>
</tr>
<tr>
  <td><tt>comments</tt></td>
  <td>String[]</td>
  <td>A comma separated list of values for identifying commented lines.  If a line read from an input
    stream begins with any of the configured values, the line is ignored.  A backslash may
    be used to escape a comma and itself.  All whitespace is preserved.
    <p>Enabling comments require the input reader passed to <tt>StreamFactory</tt> to support marking.
    Among others, <tt>BufferedReader</tt> and <tt>StringReader</tt> support marking.</p></td>
  <td>Yes</td>
  <td>No</td>
</tr>
</table>

<h3><a name="XmlStreamFormat">4.1.5. XML Streams</a></h3>
<p>The XML writer can be customized using the following properties:</p>
<table class="indent">
<tr>
  <th>Property</th>
  <th>Type</th>
  <th>Description</th>
  <th>Reader?</th>
  <th>Writer?</th>
</tr>
<tr>
  <td><tt>suppressHeader</tt></td>
  <td>boolean</td>
  <td>If set to <tt>true</tt>, the XML header is suppressed in the marshalled
  document.  Defaults to <tt>false</tt>.</td>
  <td>No</td>
  <td>Yes</td>
</tr>
<tr>
  <td><tt>version</tt></td>
  <td>String</td>
  <td>The XML header version.  Defaults to <tt>1.0</tt>.</td>
  <td>No</td>
  <td>Yes</td>
</tr>
<tr>
  <td><tt>encoding</tt></td>
  <td>String</td>
  <td>The XML header encoding.  Defaults to 
    <tt>utf-8</tt>.  Note that this setting has no bearing on the actual
    encoding of the output stream.  If set to "", an encoding attribute
    is not included in the header.</td>
  <td>No</td>
  <td>Yes</td>
</tr>
<tr>
  <td><tt>namespaces</tt></td>
  <td>String</td>
  <td>A space delimited list of XML prefixes and namespaces to declare
    on the root element of a marshalled document.  The property value
    should be formatted as
    <pre class="indent">prefix1 namespace1 prefix2 namespace2...</pre></td>
  <td>No</td>
  <td>Yes</td>
</tr>
<tr>
  <td><tt>indentation</tt></td>
  <td>Integer</td>
  <td>The number of spaces to indent each level of XML.  By default, indentation
    is disabled using a value of -1.</td>
  <td>No</td>
  <td>Yes</td>
</tr>
<tr>
  <td><tt>lineSeparator</tt></td>
  <td>String</td>
  <td>The character(s) used to separate lines when indentation is enabled. 
    By default, <tt>System.getProperty("line.separator")</tt> is used.</td>
  <td>No</td>
  <td>Yes</td>
</tr>
</table>


<h2><a name="RecordDefinition">4.2. Record Definitions</a></h2>
<p>Each record type read from an input stream or written to an output stream must be mapped 
using a <tt>record</tt> element.  A stream mapping must include at least one record.  
The record mapping is used to validate the record and bind field values to a bean object.  
A simple record configuration is shown below.</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="stream1" format="csv"&gt;
    <span class="highlight">&lt;record name="record1" class="org.beanio.example.Record"&gt;
      &lt;field name="firstName" /&gt;
      &lt;field name="lastName" /&gt;
      &lt;field name="age" /&gt;
    &lt;/record&gt;</span>
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>
<p>In this example, a CSV formatted stream is mapped to a single record composed of
three fields: first name, last name and age.  When a record is read from a stream using a <tt>BeanReader</tt>,
the class <tt>org.beanio.example.Record</tt> is instantiated and its <tt>firstName</tt>
and <tt>lastName</tt> attributes are set using standard Java bean
setter naming conventions (e.g. <tt>setFirstName(String)</tt>).</p>

<p>Similarly, when a <tt>org.beanio.example.Record</tt> bean object is written to an output stream using
a <tt>BeanWriter</tt>, its <tt>firstName</tt> and <tt>lastName</tt> attributes
are read using standard Java bean getter naming conventions (e.g. <tt>getFirstName()</tt>)
and formatted.</p>

<p>BeanIO also supports Map based records by setting a record's <tt>class</tt>
attribute to <tt>map</tt>, or to the fully qualified class name of any class assignable
to <tt>java.util.Map</tt>.  Note that if you plan to use Map based records,
field types may need be explicitly configured using the <tt>type</tt> attribute, or BeanIO
will assume the field is of type <tt>java.lang.String</tt>  The <tt>type</tt> attribute
is further explained in section <a href="#FieldTypeConversion.">4.6. Field Type Conversion</a>.</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="stream1" format="csv"&gt;
    &lt;record name="record1" <span class="highlight">class="map"</span>&gt;
      &lt;field name="firstName" /&gt;
      &lt;field name="lastName" /&gt;
      &lt;field name="age" <span class="highlight">type="int"</span>/&gt;
    &lt;/record&gt;
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>


<h3><a name="RecordIdentification">4.2.1. Record Identification</a></h3>
<p>Oftentimes, a stream is made up of multiple record types.  A typical batch file
may include one header, one trailer, and zero to many detail records.  BeanIO
allows a record to be identified by one or more of its fields using expected
literal values or regular expressions.  By default, BeanIO will validate 
the order of all records in the input stream.</p>
<p>To see how a stream can be configured to handle multiple record types, let's
modify our Employee file to include a header and trailer record as shown below.  Each record 
now includes a record type field that identifies the type of record.</p>
<pre class="file">
Header,01012011
Detail,Joe,Smith,Developer,75000,10012009
Detail,Jane,Doe,Architect,80000,01152008
Detail,Jon,Anderson,Manager,85000,03182007
Trailer,3</pre>

<p>The mapping file can now be updated as follows:</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="employeeFile" format="csv"&gt;
    &lt;record name="header" minOccurs="1" maxOccurs="1" class="org.beanio.example.Header"&gt;
      &lt;field name="recordType" rid="true" literal="Header" /&gt;
      &lt;field name="fileDate" format="MMddyyyy" /&gt;
    &lt;/record&gt;
    &lt;record name="employee" minOccurs="0" maxOccurs="unbounded" class="org.beanio.example.Employee"&gt;
      &lt;field name="recordType" rid="true" literal="Detail" /&gt;
      &lt;field name="firstName" /&gt;
      &lt;field name="lastName" /&gt;
      &lt;field name="title" /&gt;
      &lt;field name="salary" /&gt;
      &lt;field name="hireDate" format="MMddyyyy" /&gt;
    &lt;/record&gt;
    &lt;record name="trailer" minOccurs="1" maxOccurs="1" class="org.beanio.example.Trailer"&gt;
      &lt;field name="recordType" rid="true" literal="Trailer" /&gt;
      &lt;field name="recordCount" /&gt;
    &lt;/record&gt;  
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>

<p>There are several new record and field attributes introduced in this mapping
file, so we'll explain each new attribute in turn.</p>

<p>First, a field used to identify a record must be configured as a <i>record identifier</i>
using <tt>rid="true"</tt>.
There is no limitation to the number of fields that can be used to identify a record,
but all fields where <tt>rid="true"</tt> must be satisfied before a record is
identified.  If there is no field configured as a record identifier, by default 
the record will always match.</p>
<pre class="file">
    &lt;record name="header" minOccurs="1" maxOccurs="1" class="org.beanio.example.Header"&gt;
      &lt;field name="recordType" <span class="highlight">rid="true"</span> literal="Header" /&gt;
      &lt;field name="fileDate" /&gt;
    &lt;/record&gt;
</pre>

<p>Second, all record identifying fields must have a matching validation rule configured.  In
our example, the literal value <tt>Header</tt> in the record type field is used to identify
the header record.  Literal values must match exactly and can be configured using the
<tt>literal</tt> field attribute.  Alternatively, record identifying fields may
use a regular expression to match field text using the <tt>regex</tt> field attribute.
</p>
<pre class="file">
    &lt;record name="header" minOccurs="1" maxOccurs="1" class="org.beanio.example.Header"&gt;
      &lt;field name="recordType" rid="true" <span class="highlight">literal="Header"</span> /&gt;
      &lt;field name="fileDate" /&gt;
    &lt;/record&gt;
</pre>

<p>Third, each record defines the minimum and maximum number of times it may
repeat using the attributes <tt>minOccurs</tt> and <tt>maxOccurs</tt>.  Based on
our configuration, exactly one header and trailer record is required, while 
the number of detail records is unbounded.</p>
<pre class="file">
    &lt;record name="header" <span class="highlight">minOccurs="1" maxOccurs="1"</span> class="org.beanio.example.Header"&gt;
      &lt;field name="recordType" rid="true" literal="Header" /&gt;
      &lt;field name="fileDate" /&gt;
    &lt;/record&gt;
</pre>

<h3><a name="RecordOrdering">4.2.2. Record Ordering</a></h3>
<p>As explained in the previous section, a stream can support multiple record types.  By default,  
a <tt>BeanReader</tt> will validate that each record read from a stream appears in the same order
it was configured.  In the previous example, if a detail record were to appear before the header record,
the <tt>BeanReader</tt> will throw an <tt>UnexpectedRecordException</tt> when the detail
record is read out of order.</p>

<p>Default record ordering can be overridden using the <tt>order</tt> record 
attribute, which can be assigned any positive integer value greater than 0.  Records that
are assigned the same number may be read from the stream in any order.  In our current example, 
if we want to allow header and detail records to appear in any order, while still
requiring the trailer record at the end of the stream, the mapping
file could be changed as follows.</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="employeeFile" format="csv"&gt;
    &lt;record name="header" <span class="highlight">order="1"</span> minOccurs="1" maxOccurs="1" class="org.beanio.example.Header"&gt;
      &lt;field name="recordType" rid="true" literal="Header" /&gt;
      &lt;field name="fileDate" format="MMddyyyy" /&gt;
    &lt;/record&gt;
    &lt;record name="employee" <span class="highlight">order="1"</span> minOccurs="0" maxOccurs="unbounded" class="org.beanio.example.Employee"&gt;
      &lt;field name="recordType" rid="true" literal="Detail" /&gt;
      &lt;field name="firstName" /&gt;
      &lt;field name="lastName" /&gt;
      &lt;field name="title" /&gt;
      &lt;field name="salary" /&gt;
      &lt;field name="hireDate" format="MMddyyyy" /&gt;
    &lt;/record&gt;
    &lt;record name="trailer" <span class="highlight">order="2"</span> minOccurs="1" maxOccurs="1" class="org.beanio.example.Trailer"&gt;
      &lt;field name="recordType" rid="true" literal="Trailer" /&gt;
      &lt;field name="recordCount" /&gt;
    &lt;/record&gt;  
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>

<p>Or if you don't care about record ordering at all, simply set the stream's <tt>ordered</tt>
attribute to <tt>false</tt> as shown below.</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="employeeFile" format="csv" <span class="highlight">ordered="false"</span>&gt;
    &lt;!-- Record layouts... --&gt;
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>

<h3><a name="RecordGrouping">4.2.3. Record Grouping</a></h3>
<p>In some cases, a stream may be further divided into batches or groups of records.  
Continuing with our employee file, lets suppose employee detail records are batched by department,
where each group of employees has a department header and a department trailer record.  
Thus an input file may look something like this:</p>
<pre class="file">
Header,01012011
DeptHeader,Development
Detail,Joe,Smith,Developer,75000,10012009
Detail,Jane,Doe,Architect,80000,01152008
DeptTrailer,2
DeptHeader,Product Management
Detail,Jon,Anderson,Manager,85000,03182007
DeptTrailer,1
Trailer,2</pre>

<p>BeanIO allows you to define groups of records using a <tt>group</tt> element to wrap
the record types that belong to the group.  Groups
support the same <tt>order</tt>, <tt>minOccurs</tt>, and <tt>maxOccurs</tt> attributes, although
there meaning is applied to the entire group.  Once a record type is matched that belongs to a group,
all other records in that group where <tt>minOccurs</tt> is greater that 1, must be read from the stream
before the group may repeat or a different record can be read.  Our mapping file would now look like this:</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="employeeFile" format="csv"&gt;
    &lt;record name="header" minOccurs="1" maxOccurs="1" class="org.beanio.example.Header"&gt;
      &lt;field name="recordType" rid="true" literal="Header" /&gt;
      &lt;field name="fileDate" format="MMddyyyy" /&gt;
    &lt;/record&gt;
    <span class="highlight">&lt;group name="departmentGroup" minOccurs="0" maxOccurs"unbounded"&gt;</span>
      &lt;record name="deptHeader" minOccurs="1" maxOccurs="1" class="org.beanio.example.DeptHeader"&gt;
        &lt;field name="recordType" rid="true" literal="DeptHeader" /&gt;
        &lt;field name="departmentName" /&gt;
      &lt;/record&gt;
      &lt;record name="employee" minOccurs="0" maxOccurs="unbounded" class="org.beanio.example.Employee"&gt;
        &lt;field name="recordType" rid="true" literal="Detail" /&gt;
        &lt;field name="firstName" /&gt;
        &lt;field name="lastName" /&gt;
        &lt;field name="title" /&gt;
        &lt;field name="salary" /&gt;
        &lt;field name="hireDate" format="MMddyyyy" /&gt;
      &lt;/record&gt;
      &lt;record name="deptTrailer" minOccurs="1" maxOccurs="1" class="org.beanio.example.DeptTrailer"&gt;
        &lt;field name="recordType" rid="true" literal="DeptTrailer" /&gt;
        &lt;field name="employeeCount" /&gt;
      &lt;/record&gt;  
    <span class="highlight">&lt;/group&gt;</span>
    &lt;record name="trailer" minOccurs="1" maxOccurs="1" class="org.beanio.example.Trailer"&gt;
      &lt;field name="recordType" rid="true" literal="Trailer" /&gt;
      &lt;field name="departmentCount" /&gt;
    &lt;/record&gt;  
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>

<p>The stream definition itself is a record group with defaults <tt>minOccurs="0"</tt>
and <tt>maxOccurs="1"</tt>.  If you want your <tt>BeanReader</tt> to throw an exception if the stream 
is empty, simply change <tt>minOccurs</tt> to <tt>1</tt>, or if you want to allow the entire stream to repeat
indefinitely, simply change <tt>maxOccurs</tt> to <tt>unbounded</tt> as shown below.</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="employeeFile" format="csv" <span class="highlight">minOccurs="1"</span> <span class="highlight">maxOccurs="unbounded"</span>&gt;
    &lt;!-- Record layout... --&gt;
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>



<h2><a name="FieldDefinitions">4.3. Field Definitions</a></h2>
A record is made up of one or more fields, which are validated and bound to bean properties 
using the <tt>field</tt> element.  All fields must specify a <tt>name</tt> attribute, which  
by default, is used to get and set the field value from the bean object.

<p>Default getter and setter methods can be overridden using
<tt>getter</tt> and <tt>setter</tt> attributes as shown below.</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="stream1" format="csv"&gt;
    &lt;record name="record1" class="org.beanio.example.Record"&gt;
      &lt;field name="firstName" /&gt;
      &lt;field name="lastName" <span class="highlight">setter="setSurname" getter="getSurname"</span>/&gt;
      &lt;field name="age" /&gt;
    &lt;/record&gt;
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>

<p>Fields found in a stream that do not map to a bean property can be declared,
but otherwise ignored, using the <tt>ignore</tt> field attribute.  Note that
configured validation rules are still applied to ignored fields.</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="stream1" format="csv"&gt;
    &lt;record name="record1" class="org.beanio.example.Record"&gt;
      &lt;field name="firstName" /&gt;
      &lt;field name="lastName" /&gt;
      &lt;field name="age" /&gt;
      &lt;field name="filler" <span class="highlight">ignore="true"</span> /&gt;
    &lt;/record&gt;
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>

<p>By default, BeanIO expects fields to appear in a CSV, delimited or fixed length stream in the same order they
are declared in the mapping file.  If this is not the case, a <tt>position</tt> field attribute
can be configured for each field.  If a position is declared for one field, a position must be declared
for all other fields in the same record.  For delimited (and CSV) formatted streams, <tt>position</tt>
should be set to the index of the first occurrence of the field in the record, beginning at 0.  
For fixed length formatted streams, <tt>position</tt> should be set to the index of the first character
of the first occurrence of the field in the record, beginning at 0. </p>

<p>The following example shows how the position attribute can be used.  Although the fields are declared
in a different order, the record definition is identical to the previous example.  When positions are explicitly
configured for an input stream, there is no need to declare all fields in a record, unless desired 
for validation purposes.</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="stream1" format="csv"&gt;
    &lt;record name="record1" class="org.beanio.example.Record"&gt;
      &lt;field name="filler" <span class="highlight">position="3"</span> ignore="true" /&gt;
      &lt;field name="lastName" <span class="highlight">position="1"</span> /&gt;
      &lt;field name="age" <span class="highlight">position="2"</span>/&gt;
      &lt;field name="firstName" <span class="highlight">position="0"</span> /&gt;
    &lt;/record&gt;
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>

<h3><a name="FieldTypeConversion">4.3.1. Field Type Conversion</a></h3>
<p>The property type of a field is determined by introspecting the bean object the field belongs to.
If the bean class is of type <tt>java.util.Map</tt>, BeanIO will assume the field is of type
<tt>java.lang.String</tt>, unless a field type is explicitly declared using a field's <tt>type</tt>
attribute.</p>
<p>The <tt>type</tt> attribute may be set to any supported fully qualified class name or to one of the 
supported type aliases below.  Type aliases are not case sensitive, and the same alias may be
used for primitive types.  For example, <tt>int</tt> and <tt>java.lang.Integer</tt>
bean properties will use the same type handler registered for the type <tt>java.lang.Integer</tt>,
or alias <tt>integer</tt> or <tt>int</tt>.</p>
<table class="indent">
<tr><th>Class Name</th><th>Primitive</th><th>Alias(es)</th></tr>
<tr><td>java.lang.String</td><td>-</td><td><tt>string</tt></td></tr>
<tr><td>java.lang.Boolean</td><td>boolean</td><td><tt>boolean</tt></td></tr>
<tr><td>java.lang.Byte</td><td>byte</td><td><tt>byte</tt></td></tr>
<tr><td>java.lang.Character</td><td>char</td><td><tt>character</tt><br /><tt>char</tt></td></tr>
<tr><td>java.lang.Short</td><td>short</td><td><tt>short</tt></td></tr>
<tr><td>java.lang.Integer</td><td>int</td><td><tt>integer</tt><br /><tt>int</tt></td></tr>
<tr><td>java.lang.Long</td><td>long</td><td><tt>long</tt></td></tr>
<tr><td>java.lang.Float</td><td>float</td><td><tt>float</tt></td></tr>
<tr><td>java.lang.Double</td><td>double</td><td><tt>double</tt></td></tr>
<tr><td>java.math.BigInteger</td><td>-</td><td><tt>biginteger</tt></td></tr>
<tr><td>java.math.BigDecimal</td><td>-</td><td><tt>bigdecimal</tt><br /><tt>decimal</tt></td></tr>
<tr><td>java.util.Date<sup>1</sup></td><td>-</td>
  <td>
    <tt>datetime</tt><br />
    <tt>date</tt><br />
    <tt>time</tt>
  </td>
</tr>
</table>
<p class="indent"><sup>1</sup> By default, the <tt>date</tt> alias is used for <tt>java.util.Date</tt> types that 
contain date information only, and the <tt>time</tt> alias is used for <tt>java.util.Date</tt> types that contain 
only time information.  Only the <tt>datetime</tt> alias can be used to replace the default class type handler 
for <tt>java.util.Date</tt>.</p>

<p>Optionally, a <tt>format</tt> attribute can be used to pass a decimal format for <tt>java.lang.Number</tt> types, and
for passing a date format for <tt>java.util.Date</tt> types.  In the example below, the <tt>hireDate</tt> field
uses the <tt>SimpleDateFormat</tt> pattern "yyyy-MM-dd", and the <tt>salary</tt> field uses the <tt>DecimalFormat</tt>
pattern "#,##0".


In the example below, a 
<tt>DateTypeHandler</tt> is registered for all <tt>java.util.Date</tt> types and used by the <tt>fileDate</tt> 
field.  The <tt>hireDate</tt> field overrides the pattern of the default date type handler using
the <tt>format</tt> attribute.</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="employeeFile" format="csv"&gt;
    &lt;record name="header" minOccurs="1" maxOccurs="1" class="map"&gt;
      &lt;field name="recordType" rid="true" literal="Header" /&gt;
      &lt;field name="fileDate" <span class="highlight">type="java.util.Date"</span> /&gt;
    &lt;/record&gt;
    &lt;record name="employee" minOccurs="0" maxOccurs="unbounded" class="map"&gt;
      &lt;field name="recordType" rid="true" literal="Detail" /&gt;
      &lt;field name="firstName" /&gt;
      &lt;field name="lastName" /&gt;
      &lt;field name="title" /&gt;
      &lt;field name="salary" <span class="highlight">type="int" format="#,##0"</span> /&gt;
      &lt;field name="hireDate" <span class="highlight">type="date" format="yyyy-MM-dd"</span> /&gt;
    &lt;/record&gt;
    &lt;record name="trailer" minOccurs="1" maxOccurs="1" class="map"&gt;
      &lt;field name="recordType" rid="true" literal="Trailer" /&gt;
      &lt;field name="recordCount" <span class="highlight">type="int"</span> /&gt;
    &lt;/record&gt;  
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>




<h3><a name="CustomTypeHandlers">4.3.2. Custom Type Handlers</a></h3>
<p>Field type conversion is performed by a <i>type handler</i>.  BeanIO includes type handlers
for common Java types, or you can create your own type handler by implementing the 
<tt>org.beanio.types.TypeHandler</tt> interface shown below.
When writing a custom type handler, make sure to handle null values and empty strings.
Only one instance of your type handler is created, so if you plan to concurrently read or write
multiple streams, make sure your type handler is also thread safe.
</p>
<pre class="java">
package org.beanio.types;

public interface TypeHandler {
    public Object parse(String text) throws TypeConversionException;
    public String format(Object value);
    public Class&lt;?&gt; getType();
}</pre>

<p>The following example shows a custom type handler for the <tt>java.lang.Boolean</tt> class
and <tt>boolean</tt> primitive based on "Y" or "N" indicators.</p>
<pre class="java">
import org.beanio.types.TypeHandler;

public class YNTypeHandler implements TypeHandler {
    public Object parse(String text) throws TypeConversionException {
        return "Y".equals(text);
    }
    public String format(Object value) {
        return value != null &amp;&amp; ((Boolean)value).booleanValue() ? "Y" : "N";
    }
    public Class&lt;?&gt; getType() {
        return Boolean.class;
    }
}</pre>


<p>A type handler may be explicitly named using the <tt>name</tt> attribute, and/or registered for
all fields of a particular type by setting the <tt>type</tt> attribute.  The <tt>type</tt> attribute can be
be set to the fully qualified class name or type alias of the class supported by the type handler.
To reference a named type handler, use the <tt>typeHandler</tt> field attribute when configuring
the field.</p>

<p>Many default type handlers included with BeanIO support customization through the use of 
one or more <tt>property</tt> elements, where the <tt>name</tt> attribute is a bean property of 
the type handler, and the <tt>value</tt> attribute is the property value.</p>

<p>Type handlers can be declared globally (for all streams in the mapping file) or for a specific stream.
Globally declared type handlers may optionally use a <tt>format</tt> attribute to narrow the type handler
scope to a specific stream format.</p>

<p>In the example below, the first <tt>DateTypeHandler</tt> is declared globally for all stream formats.  The
second <tt>DateTypeHandler</tt> overrides the first for <tt>java.util.Date</tt> types in an XML formatted stream, 
and the <tt>YNTypeHandler</tt> is declared only for the 'employeeFile' stream.  Stream specific type handlers 
override global type handlers when declared with the same name or for the same type.</p>
<pre class="file">
&lt;beanio&gt;

  &lt;typeHandler <span class="highlight">type="java.util.Date"</span> class="org.beanio.types.DateTypeHandler"&gt;
    <span class="highlight">&lt;property name="pattern" value="MMddyyyy" /&gt;</span>
    <span class="highlight">&lt;property name="lenient" value="true" /&gt;</span>
  &lt;/typeHandler&gt;
  &lt;typeHandler type="java.util.Date" <span class="highlight">format="xml"</span> class="org.beanio.types.DateTypeHandler"&gt;
    &lt;property name="pattern" value="yyyy-MM-dd" /&gt;
  &lt;/typeHandler&gt;

  &lt;stream name="employeeFile" format="csv"&gt;
    &lt;typeHandler <span class="highlight">name="ynHandler"</span> class="org.beanio.example.YNTypeHandler" /&gt;
  
    &lt;record name="employee" minOccurs="0" maxOccurs="unbounded" class="map"&gt;
      &lt;field name="recordType" rid="true" literal="Detail" /&gt;
      &lt;field name="firstName" /&gt;
      &lt;field name="lastName" /&gt;
      &lt;field name="title" /&gt;
      &lt;field name="salary" /&gt;
      &lt;field name="hireDate" /&gt;
      &lt;field name="exempt" <span class="highlight">typeHandler="ynHandler"</span> /&gt;
    &lt;/record&gt; 
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>

<h3><a name="CollectionFields">4.3.3. Collection Type Fields</a></h3>
<p>Collection and array field property types are also supported by BeanIO.  For example, lets assume our 
<tt>Employee</tt> bean object contains a list of accounts.</p>
<pre class="java">
package org.beanio.example;
import java.util.Date;

public class Employee {
    String firstName;
    String lastName;
    String title;
    int salary;
    Date hireDate;
    <span class="highlight">List&lt;Integer&gt; accounts;</span>
    
    <span class="comment">// getters and setters not shown...</span>
}</pre>

<p>And lets assume our input file now looks like this:</p>
<pre class="file">
Joe,Smith,Developer,75000,10012009
Chris,Johnson,Sales,80000,05292006<span class="highlight">,100012,200034,200045</span>
Jane,Doe,Architect,80000,01152008
Jon,Anderson,Manager,85000,03182007<span class="highlight">,333001</span></pre>

<p>In this example, the <tt>accounts</tt> bean property can be defined in the mapping file using a <tt>collection</tt> 
field attribute.  The <tt>collection</tt> attribute can be set to the fully qualified class name of
a <tt>java.util.Collection</tt> subclass, or to one of the collection type aliases below.</p>  
<table class="indent">
<tr><th>Class</th><th>Alias</th><th>Default Implementation</th></tr>
<tr><td>java.util.Collection</td><td><tt>collection</tt></td><td>java.util.ArrayList</td></tr>
<tr><td>java.util.List</td><td><tt>list</tt></td><td>java.util.ArrayList</td></tr>
<tr><td>java.util.Set</td><td><tt>set</tt></td><td>java.util.HashSet</td></tr>
<tr><td>(Java Array)</td><td><tt>array</tt></td><td>N/A</td></tr>
</table>

<p>Collection type fields can declare the number of occurrences of the field
using <tt>minOccurs</tt> and <tt>maxOccurs</tt> field attributes.  If not declared, <tt>minOccurs</tt>
will default to 1, and <tt>maxOccurs</tt> will default to the <tt>minOccurs</tt> value or 1, whichever
is greater.  If the number of field occurences is variable (i.e. <tt>maxOccurs</tt> is greater than 
<tt>minOccurs</tt>), the field must be the last field in the record.
</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="employeeFile" format="csv"&gt;
    &lt;record name="employee" class="org.beanio.example.Employee"&gt;
      &lt;field name="firstName" /&gt;
      &lt;field name="lastName" /&gt;
      &lt;field name="title" /&gt;
      &lt;field name="salary" /&gt;
      &lt;field name="hireDate" format="MMddyyyy" /&gt;
      &lt;field name="accounts" type="int" <span class="highlight">collection="list" minOccurs="0" maxOccurs="unbounded"</span> /&gt;
    &lt;/record&gt; 
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>


<h3><a name="FixedLengthFields">4.3.4. Fixed Length Fields</a></h3>
<p>Fixed length fields require a little extra configuration than their delimited counterparts.  Let's
redefine our employee file example using the fixed length format below.
</p>
<div class="indent">
  <table>
    <tr><th>Position</th><th>Field</th><th>Format</th><th>Length</th></tr>
    <tr><td>0</td><td>First Name</td><td>Text</td><td>10</td></tr>
    <tr><td>10</td><td>Last Name</td><td>Text</td><td>10</td></tr>
    <tr><td>20</td><td>Job Title</td><td>Text</td><td>10</td></tr>
    <tr><td>30</td><td>Salary</td><td>Number</td><td>6</td></tr>
    <tr><td>36</td><td>Hire Date</td><td>Date (MMDDYYYY)</td><td>8</td></tr>
  </table>
</div>

<p>A fixed length version of the employee file might look like the following:</p>
<pre class="file">
Joe       Smith    Developer 07500010012009
Jane      Doe      Architect 08000001152008
Jon       Anderson Manager   08500003182007</pre>

<p>The length of a fixed length field must be configured using the <tt>length</tt> field attribute.
By default, fixed length fields are left justified and padded with spaces, but these settings can
be overridden using the <tt>padding</tt> and <tt>justify</tt> field attributes.  Field padding can
be set to any single character, and field justification can be set to <tt>left</tt> or <tt>right</tt>.
Using these attributes, our mapping file can now be updated as follows:  
</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="employeeFile" format="csv"&gt;
    &lt;record name="employee" class="org.beanio.example.Employee"&gt;
      &lt;field name="firstName" <span class="highlight">length="10"</span> /&gt;
      &lt;field name="lastName" <span class="highlight">length="10"</span> /&gt;
      &lt;field name="title" <span class="highlight">length="10"</span> /&gt;
      &lt;field name="salary" <span class="highlight">length="6" padding="0" justify="right"</span> /&gt;
      &lt;field name="hireDate" <span class="highlight">length="8"</span> format="MMddyyyy" /&gt;
    &lt;/record&gt; 
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>

<p>The configured padding character is removed from the beginning of the field if right justified, or 
from the end of the field if left justified, until a character is found that does not match the padding
character.  If the entire field is padded, <tt>Number</tt> property types default to the padding character if 
it is a digit, and the padding character is ignored for <tt>Character</tt> types.  To illustrate this, 
some examples are shown in the table below.</p>
<table class="indent">
<tr>
  <th>Justify</th>
  <th>Type</th>
  <th>Padding</th>
  <th>Padded Text</th>
  <th>Unpadded Text</th>
</tr>
<tr>
  <td rowspan="4"><tt>left</tt></td>
  <td rowspan="2"><tt>String</tt></td>
  <td rowspan="2"><tt>"&nbsp;"</tt></td>
  <td>
    <tt>"George&nbsp;&nbsp;"</tt>
  </td>
  <td><tt>"George"</tt></td>
</tr>
<tr>
  <td><tt>"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"</tt></td>
  <td><tt>""</tt></td>
</tr>
<tr>
  <td rowspan="2"><tt>Character</tt></td>
  <td rowspan="2"><tt>"&nbsp;"</tt></td>
  <td><tt>"A"</tt></td>
  <td><tt>"A"</tt></td>
</tr>
<tr>
  <td><tt>" "</tt></td>
  <td><tt>" "</tt></td>
</tr>
<tr>
  <td rowspan="5"><tt>right</tt></td>
  <td rowspan="5"><tt>Number</tt></td>
  <td rowspan="2"><tt>"0"</tt></td>
  <td><tt>"00123"</tt></td>
  <td><tt>"123"</tt></td>
</tr>
<tr>
  <td><tt>"00000"</tt></td>
  <td><tt>"0"</tt></td>
</tr>
<tr>
  <td rowspan="2"><tt>"9"</tt></td>
  <td><tt>"00000"</tt></td>
  <td><tt>"00000"</tt></td>
</tr>
<tr>
  <td><tt>"99999"</tt></td>
  <td><tt>"9"</tt></td>
</tr>
<tr>
  <td rowspan="1"><tt>"X"</tt></td>
  <td><tt>"XXXXX"</tt></td>
  <td><tt>""</tt></td>
</tr>
</table>

<p>The marshalling and unmarshalling behavior of null field values for a padded field is
further controlled using the <tt>required</tt> attribute.  If <tt>required</tt> is set to true, null
field values are marshalled by filling the field with the padding character.  If
<tt>required</tt> is set to false, a null field value is marshalled as spaces for fixed length
streams and an empty string for non-fixed length streams.  Similarly, if <tt>required</tt> is set to
false, spaces are unmarshalled to a null field value regardless of the padding character.
To illustrate this, the following table shows the field text for a right justified zero
padded 3 digit number.</p>

<table class="indent">
<tr>
  <th>Required</th>
  <th>Field Value</th>
  <th>Field Text<br /> (Fixed Length)</th>
  <th>Field Text<br />(Non-Fixed Length)</th>
</tr>
<tr>
  <td rowspan="2"><tt>true</tt></td>
  <td>0</td>
  <td>"<tt>000</tt>"</td>
  <td>"<tt>000</tt>"</td>
</tr>
<tr>
  <td>null</td>
  <td>"<tt>000</tt>"<sup>1</sup></td>
  <td>"<tt>000</tt>"<sup>1</sup></td>
</tr>
<tr>
  <td rowspan="2"><tt>false</tt></td>
  <td>0</td>
  <td>"<tt>000</tt>"</td>
  <td>"<tt>000</tt>"</td>
</tr>
<tr>
  <td>null</td>
  <td>"<tt>&nbsp;&nbsp;&nbsp;</tt>"</td>
  <td>""</td>
</tr>
</table>
<p class="indent"><sup>1</sup> Applies to marshalling only.  Unmarshalling "000" would
produce a field value of 0.</p>
<p>As hinted to above, padding settings can be applied to any field for any stream type.</p>


<h2><a name="PropertyDefinitions">4.4. Property Definitions</a></h2>
<p>If a bean property does not map to a field in the input or output stream, the property
value can still be set using a <tt>property</tt> element.  Like a field, all properties must 
specify a <tt>name</tt> attribute, which by default, is used to get and set the property value 
from the bean object.  Properties also require a <tt>value</tt> attribute for setting the textual
representation of the property value.  The value text is type converted using the same rules
and attributes (<tt>type</tt>, <tt>typeHandler</tt> and <tt>format</tt>) used for
field type conversion described above.  Collection type properties are not supported.</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="employeeFile" format="csv"&gt;
    &lt;record name="employee" class="map"&gt;
      <span class="highlight">&lt;property name="recordType" value="employee" /&gt;</span>
      &lt;field name="firstName" /&gt;
      &lt;field name="lastName" /&gt;
      &lt;field name="title" /&gt;
      &lt;field name="salary" /&gt;
      &lt;field name="hireDate" format="MMddyyyy" /&gt;
    &lt;/record&gt; 
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>

<p>Properties are particularly useful in two scenarios:</p>
<ul>
<li>When reading an input stream (unmarshalling), if multiple records are mapped to the same bean class, such as a Map,
a property can be used to set a property, or a Map key, for identifying the record type without querying the 
<tt>BeanReader</tt></li>
<li>When writing an output stream (marshalling), a record mapping can be selected based on a record identifying
property value by setting <tt>rid</tt> to true.  This allows the same bean class to be unmarshalled to different
record types based on a property that may not exist in the output stream.</li>
</ul>

<h2><a name="BeanDefinitions">4.5. Nested Bean Definitions</a></h2>
<p>The bean class mapped to a record can be divided into nested bean objects using
a <tt>bean</tt> element.  First, let's suppose we store an address in our CSV employee
file, so that the record layout might look like this:</p>
<table class="indent">
  <tr><th>Position</th><th>Field</th><th>Format</th></tr>
  <tr><td>0</td><td>First Name</td><td>Text</td></tr>
  <tr><td>1</td><td>Last Name</td><td>Text</td></tr>
  <tr><td>2</td><td>Job Title</td><td>Text</td></tr>
  <tr><td>3</td><td>Salary</td><td>Number</td></tr>
  <tr><td>4</td><td>Hire Date</td><td>Date (MMDDYYYY)</td></tr>
  <tr><td>5</td><td>Street</td><td>Text</td></tr>
  <tr><td>6</td><td>City</td><td>Text</td></tr>
  <tr><td>7</td><td>State</td><td>Text</td></tr>
  <tr><td>8</td><td>Zip</td><td>Text</td></tr>
</table>

<p>Second, lets suppose we want to store address information in a new <tt>Address</tt>
bean object like the one below, and add an <tt>Address</tt> reference to our
<tt>Employee</tt> class.</p>
<pre class="java">
package org.beanio.example;

public class Address {
    String street;
    String city;
    String state;
    String zip;
    
    <span class="comment">// getters and setters not shown...</span>
}</pre>
<pre class="java">
package org.beanio.example;
import java.util.Date;

public class Employee {
    String firstName;
    String lastName;
    String title;
    int salary;
    Date hireDate;
    Address mailingAddress;
    
    <span class="comment">// getters and setters not shown...</span>
}</pre>

<p>With this information, we can now update our employee CSV mapping file to 
accomodate the nested <tt>Address</tt> object.  A <tt>bean</tt> element must include 
<tt>name</tt> and <tt>class</tt> attributes.  By default, the <tt>name</tt> attribute is
used to determine the getter and setter on its parent bean or record.  Optionally, 
<tt>getter</tt> or <tt>setter</tt> attributes can be used to override the default property
name similar to a field property.  And the <tt>class</tt> attribute must be set to the fully
qualified class name of the bean object, or to <tt>map</tt>, or to the class name of 
any concrete <tt>java.util.Map</tt> implementation.  If the bean class is of type <tt>java.util.Map</tt>,
field values are stored in the Map under their configured field name.</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="employeeFile" format="csv"&gt;
    &lt;record name="employee" class="org.beanio.example.Employee"&gt;
      &lt;field name="firstName" /&gt;
      &lt;field name="lastName" /&gt;
      &lt;field name="title" /&gt;
      &lt;field name="salary" /&gt;
      &lt;field name="hireDate" format="MMddyyyy" /&gt;
      <span class="highlight">&lt;bean name="mailingAddress" class="org.beanio.example.Address"&gt;
        &lt;field name="street" /&gt;
        &lt;field name="city" /&gt;
        &lt;field name="state" /&gt;      
        &lt;field name="zip" /&gt;
      &lt;/bean&gt;</span>
    &lt;/record&gt; 
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>

<p>If needed, nested bean objects can be further divided into other bean objects.  There is no limit
to the number of nested levels that can be configured in a mapping file.</p>

<h3><a name="BeanCollections">4.5.1. Collection Type Beans</a></h3>
<p>Similar to collection type fields, BeanIO also supports collection type beans.  Continuing our previous
example, let's suppose the employee CSV file may contain 1 or more addresses for each employee.  Thus our 
<tt>Employee</tt> bean object might look like this:</p>
<pre class="java">
package org.beanio.example;
import java.util.Date;

public class Employee {
    String firstName;
    String lastName;
    String title;
    int salary;
    Date hireDate;
    List&lt;Address&gt; addressList;
    
    <span class="comment">// getters and setters not shown...</span>
}</pre>

<p>And our input file might look like this:</p>
<pre class="file">
Joe,Smith,Developer,75000,10012009,123 State St,Chicago,IL,60614
Jane,Doe,Architect,80000,01152008,456 Main St,Chicago,IL,60611,111 Michigan Ave,Chicago,IL,60611
Jon,Anderson,Manager,85000,03182007,1212 North Ave,Chicago,IL,60614</pre>

<p>In our mapping file, in order to designate a bean as a collection, simply set it's <tt>collection</tt> 
attribute to the fully qualified class name of a <tt>java.util.Collection</tt> subclass,
or to one of the collection type aliaes below.</p>
<table class="indent">
<tr><th>Class</th><th>Alias</th><th>Default Implementation</th></tr>
<tr><td>java.util.Collection</td><td><tt>collection</tt></td><td>java.util.ArrayList</td></tr>
<tr><td>java.util.List</td><td><tt>list</tt></td><td>java.util.ArrayList</td></tr>
<tr><td>java.util.Set</td><td><tt>set</tt></td><td>java.util.HashSet</td></tr>
<tr><td>(Java Array)</td><td><tt>array</tt></td><td>N/A</td></tr>
</table>

<p>Just like a collection type field, collection type beans may declare the number of occurrences
using <tt>minOccurs</tt> and <tt>maxOccurs</tt> bean attributes.  If not declared, <tt>minOccurs</tt>
will default to 1, and <tt>maxOccurs</tt> will default to the <tt>minOccurs</tt> value or 1, whichever
is greater.  If the number of occurences is variable (i.e. <tt>maxOccurs</tt> is greater than 
<tt>minOccurs</tt>), the bean must be the last segment in the record.
</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="employeeFile" format="csv"&gt;
    &lt;record name="employee" class="org.beanio.example.Employee"&gt;
      &lt;field name="firstName" /&gt;
      &lt;field name="lastName" /&gt;
      &lt;field name="title" /&gt;
      &lt;field name="salary" /&gt;
      &lt;field name="hireDate" format="MMddyyyy" /&gt;
      &lt;bean name="addressList" <span class="highlight">collection="list" minOccurs="1" maxOccurs="unbounded"</span>
          class="org.beanio.example.Address"&gt;
        &lt;field name="street" /&gt;
        &lt;field name="city" /&gt;
        &lt;field name="state" /&gt;      
        &lt;field name="zip" /&gt;
      &lt;/bean&gt;
    &lt;/record&gt; 
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>

<p>When working with collection type beans, there are a few restrictions to keep in mind:</p>
<ul>
  <li>Bean fields must repeat consecutively in the record.</li>
  <li>All repeating bean fields must be declared.  There can be no field gaps in the bean configuration.</li>
  <li>A colllection type bean may not contain any collection type descendents with variable occurrences.</li>
</ul>




<h2><a name="StreamValidation">4.6. Stream Validation</a></h2>
<p>A <tt>BeanReader</tt> will throw an <tt>InvalidRecordException</tt> if a record or one of 
its fields fails a configured validation rule.  There are two types of errors reported
for an invalid record: record level errors and field level errors.  If a record level error occurs, 
further processing of the record is aborted and an excception is immediatedly thrown.  If a field level error is 
reported, the <tt>BeanReader</tt> will continue to process the record's other fields before throwing 
an exception.</p>

<p>When an <tt>InvalidRecordException</tt> is thrown, the exception will contain the reported
record and field level errors.  The following code shows how this information
can be accessed using the <tt>BeanReaderContext</tt>.</p>

<pre class="java">
    BeanReader in;
    try {
        Object record = in.read();
        if (record != null) {
            <span class="comment">// process record...</span>
        }
    }
    catch (InvalidRecordException ex) {
        BeanReaderContext context = ex.getContext();
        if (context.hasRecordErrors()) {
            for (String error : context.getRecordErrors()) {
                <span class="comment">// handle record errors...</span>
            }
        }
        if (context.hasFieldErrors()) {
            for (String field : context.getFieldErrors().keySet()) {
                for (String error : context.getFieldErrors(field)) {
                    <span class="comment">// handle field error...</span>
                }
            }
        }
    }               
}
</pre>

<p>Alternatively, it may be simpler to register a <tt>BeanReaderErrorHandler</tt> for handling
non-fatal exceptions.  The example below shows how invalid records could be written to a 
reject file by extending <tt>BeanReaderErrorHandlerSupport</tt>.
</p>

<pre class="java">
    BeanReader input;
    BufferedWriter rejects;
    try {
        input.setErrorHandler(new BeanReaderErrorHandlerSupport() {
            public void invalidRecord(InvalidRecordException ex) throws Exception {
                rejects.write(ex.getContext().getRecordText());
                rejects.newLine();
            }
        });
        
        Object record = null;
        while ((record = input.read()) != null) {
            <span class="comment">// process a valid record</span>
        }
        
        rejects.flush();
    }
    finally {
        input.close();
        rejects.close();
    }
</pre>

<p>Record and field level error messages can be customized and localized through
the use of resource bundles.  A resource bundle is
configured at the stream level using the <tt>resourceBundle</tt> attribute as
shown below.</p>
<pre class="file">
&lt;beanio&gt;

  &lt;typeHandler type="java.util.Date" class="org.beanio.types.DateTypeHandler"&gt;
    &lt;property name="pattern" value="MMddyyyy" /&gt;
  &lt;/typeHandler&gt;

  &lt;stream name="employeeFile" format="csv" <span class="highlight">resourceBundle="org.beanio.example.messages"</span> &gt;
    &lt;record name="employee" class="map"&gt;
      &lt;field name="recordType" rid="true" literal="Detail" /&gt;
      &lt;field name="firstName" /&gt;
      &lt;field name="lastName" /&gt;
      &lt;field name="title" /&gt;
      &lt;field name="salary" /&gt;
      &lt;field name="hireDate" /&gt;
    &lt;/record&gt; 
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>

<p>Record level error messages are retrieved using the following prioritized 
list of keys.  If a message is not configured under the name of the first key, the next key
will be tried until a message is found, or a default message is used.</p>
<ol>
  <li><tt>recorderror.[record name].[rule]</tt></li>
  <li><tt>recorderror.[rule]</tt></li>
</ol>
<p>Similarly, field level error messages are retrieved using the following priortized list of keys:</p>
<ol>
  <li><tt>fielderror.[record name].[field name].[rule]</tt></li>
  <li><tt>fielderror.[record name].[rule]</tt></li>
  <li><tt>fielderror.[rule]</tt></li>
</ol>  
<p>More descriptive or localized labels can also be configured for record and field names using the keys 
<tt>label.[record name]</tt> and <tt>label.[record name].[field name]</tt>
respectively.</p>

<p>For example, the following resource bundle could be used to customize
a few error messages for the employee file.</p>
<pre class="file">
<span class="comment"># 'employee' record label:</span>
label.employee = Employee Record
<span class="comment"># 'firstName' field label:</span>
label.employee.firstName = First Name Field
<span class="comment"># Unidentified record error message:</span>
recorderror.unidentified = Unidentified record at line {0}
<span class="comment"># Type conversion error message for the 'hireDate' field:</span>
fielderror.employee.hireDate.type = Invalid date format
<span class="comment"># Maximum field length error message for all fields:</span>
fielderror.maxLength = Maximum field length exceeded for {3}
</pre>

<p>Error messages are formatted using a <tt>java.text.MessageFormat</tt>.  Depending
on the validation rule that was violated, different parameters are passed to the 
<tt>MessageFormat</tt>.  
<a href="#B">Appendix B</a> documents the parameters passed to the <tt>MessageFormat</tt> for each
validation rule.</p>


<h3><a name="RecordValidation">4.6.1. Record Validation</a></h3>
<p>The following record level validation rules may be configured on a <tt>record</tt> element.
</p>
<table>
<tr><th>Attribute</th><th>Argument Type</th><th>Description</th></tr>
<tr>
  <td><tt>minLength</tt></td>
  <td>Integer</td>
  <td>Validates the record contains at least <tt>minLength</tt> fields for delimited and CSV formatted streams,
    or has at least <tt>minLength</tt> characters for fixed length formatted streams.</td>
</tr>
<tr>
  <td><tt>maxLength</tt></td>
  <td>Integer</td>
  <td>Validates the record contains at most <tt>maxLength</tt> fields for delimited and CSV formatted streams,
    or has at most <tt>maxLength</tt> characters for fixed length formatted streams.</td>
</tr>
</table>

<h3><a name="FieldValidation">4.6.2. Field Validation</a></h3>
<p>BeanIO supports several common field validation rules when reading an input stream.  All field 
validation rules are validated against the field text before type conversion.  When field trimming 
is enabled, <tt>trim="true"</tt>, all validations are performed
after the field's text has first been trimmed.  Field validations are ignored when 
writing to an output stream.
</p>
<p>The following table lists supported field attributes for validation.</p>
<table>
<tr><th>Attribute</th><th>Argument Type</th><th>Description</th></tr>
<tr>
  <td><tt>required</tt></td>
  <td>Boolean</td>
  <td>When set to <tt>true</tt>, validates the field is present and the field text is 
  not the empty string.</td>
</tr>
<tr>
  <td><tt>minLength</tt></td>
  <td>Integer</td>
  <td>Validates the field text is at least N characters.</td>
</tr>
<tr>
  <td><tt>maxLength</tt></td>
  <td>Integer</td>
  <td>Validates the field text does not exceed N characters.</td>
</tr>
<tr>
  <td><tt>literal</tt></td>
  <td>String</td>
  <td>Validates the field text exactly matches the literal value.</td>
</tr>
<tr>
  <td><tt>regex</tt></td>
  <td>String</td>
  <td>Validates the field text matches the given regular expression pattern.</td>
</tr>
<tr>
  <td><tt>minOccurs</tt></td>
  <td>String</td>
  <td>Applies to collection type fields only.  Validates the minimum occurrences
    of the field in the stream.  If the field is present in the stream, <tt>minOccurs</tt>
    is satisfied, and the <tt>required</tt> setting determines whether a value is required.</td>
</tr>
</table>


<h2><a name="Templates">4.7. Templates</a></h2>
<p>When a common set of fields is used by multiple record types, configuration may
be simplified using templates.  A template is a reusable list of bean properties (fields,
properties and child beans) that can be included by a record, bean or other template.
The following example illustrates some of the ways a template can be used:</p>

<pre class="file">
&lt;beanio&gt;

  <span class="highlight">&lt;template name="address"&gt;
    &lt;field name="street1" /&gt;
    &lt;field name="street2" /&gt;
    &lt;field name="city" /&gt;
    &lt;field name="state" /&gt;
    &lt;field name="zip" /&gt;
  &lt;/template&gt;</span>

  &lt;template name="employee"&gt;
    &lt;field name="firstName" /&gt;
    &lt;field name="lastName" /&gt;
    &lt;field name="title" /&gt;
    &lt;field name="salary" /&gt;
    &lt;field name="hireDate" format="MMddyyyy" /&gt;
    &lt;bean name="mailingAddress" <span class="highlight">template="address"</span> class="org.beanio.example.Address" /&gt;
  &lt;/template&gt;
      
  &lt;stream name="employeeFile" format="csv"&gt;
    &lt;record name="employee" <span class="highlight">template="employee"</span> class="org.beanio.example.Employee" /&gt;
  &lt;/stream&gt;

  &lt;stream name="addressFile" format="csv"&gt;
    &lt;record name="address" class="org.beanio.example.Address"&gt;
      &lt;field name="location" /&gt;
      <span class="highlight">&lt;include template="address"/&gt;</span>
      &lt;field name="attention" /&gt;
    &lt;/record&gt; 
  &lt;/stream&gt;

&lt;/beanio&gt;</pre>

<p>Templates are essentially copied into their destination using the <tt>include</tt> element.
For convenience, <tt>record</tt> and <tt>bean</tt> elements support a <tt>template</tt> attribute
which includes the template before any other children.</p>

<p>The <tt>include</tt> element can optionally specify a positional offset for included fields
using the <tt>offset</tt> attribute.  The following example illustrates this behavior.  Even when
using templates, remember that <tt>position</tt> must be declared for all fields or none.</p>

<pre class="file">
&lt;beanio&gt;

  &lt;template name="address"&gt;
    &lt;field name="street1" position="0" /&gt;
    &lt;field name="street2" position="1" /&gt;
    &lt;field name="city" position="2" /&gt;
    &lt;field name="state" position="3" /&gt;
    &lt;field name="zip" position="4" /&gt;
  &lt;/template&gt;

  &lt;stream name="addressFile" format="csv"&gt;
    &lt;record name="address" class="org.beanio.example.Address"&gt;
      &lt;field name="location" position="0" /&gt;
      &lt;include template="address" <span class="highlight">offset="1"</span>/&gt;
      &lt;field name="attention" position="6" /&gt;
    &lt;/record&gt; 
  &lt;/stream&gt;

&lt;/beanio&gt;</pre>


<!-- 

  5.0. MAPPING XML FORMATTED STREAMS
  
 -->
<h1><a name="MappingXmlStreams">5.0. Mapping XML Streams</a></h1>
<p>This section provides further details for using BeanIO to marshall and unmarshall
Java objects to and from XML formatted streams.   This section assumes you are already familiar with 
the mapping file concepts documented in previous sections.</p>
<h2><a name="XmlIntroduction">5.1. Introduction</a></h2>
<p>BeanIO is similar to other OXM (Object to XML Mapping) libraries, except that it is also capable
of marshalling and unmarshalling extremely large XML files by reading and writing Java beans one
record at a time.  BeanIO uses a streaming XML (StAX) parser to read and write XML, and will never 
hold more than the minimum amount of XML in memory needed to marshall or unmarshall a single bean object.
That said, it is still possible to run out of memory (heap space) with poorly designed XML documents and/or misconfigured
mapping files.</p>

<h3><a name="MyFirstXmlStream">5.1.1. My First XML Stream</a></h3>
<p>Before diving into the details, let's start with a basic example using the employee input file
from <a href="#MyFirstStream">Section 2.1</a> after it's been converted to XML (shown below).</p>
<pre class="file">
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;employeeFile&gt;
  &lt;employee&gt;
    &lt;firstName&gt;Joe&lt;/firstName&gt;
    &lt;lastName&gt;Smith&lt;/lastName&gt;
    &lt;title&gt;Developer&lt;/title&gt;
    &lt;salary&gt;75000&lt;/salary&gt;
    &lt;hireDate&gt;2009-10-12&lt;/hireDate&gt;
  &lt;/employee&gt;
  &lt;employee&gt;
    &lt;firstName&gt;Jane&lt;/firstName&gt;
    &lt;lastName&gt;Doe&lt;/lastName&gt;
    &lt;title&gt;Architect&lt;/title&gt;
    &lt;salary&gt;80000&lt;/salary&gt;
    &lt;hireDate&gt;2008-01-15&lt;/hireDate&gt;
  &lt;/employee&gt;
  &lt;employee&gt;
    &lt;firstName&gt;Jon&lt;/firstName&gt;
    &lt;lastName&gt;Andersen&lt;/lastName&gt;
    &lt;title&gt;Manager&lt;/title&gt;
    &lt;salary&gt;85000&lt;/salary&gt;
    &lt;hireDate&gt;2007-03-18&lt;/hireDate&gt;
  &lt;/employee&gt;
&lt;/employeeFile&gt;
</pre>

<p>In this example, let's suppose we are unmarshalling the XML employee file into the same
<tt>Employee</tt> bean object from Section 2.1 and repeated below.</p>
<pre class="java">
package org.beanio.example;
import java.util.Date;

public class Employee {
    String firstName;
    String lastName;
    String title;
    int salary;
    Date hireDate;
    
    <span class="comment">// getters and setters not shown...</span>
}</pre>

<p>Our original mapping file from Section 2.1 can now be updated to parse XML instead of
CSV with only two minor changes.  First, the stream format is changed to
<tt>xml</tt>.  And second, the hire date field format is removed and replaced with 
<tt>type="date"</tt>.  With XML, the date format does not need to be explicity declared
because it conforms to the W3C XML Schema date syntax.  (This will be further explained
in <a href="#XmlTypeConversion">Section 5.7.1</a>).</p>
<pre class="file">
&lt;beanio xmlns="http://www.beanio.org/2011/01" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.beanio.org/2011/01 http://www.beanio.org/2011/01/mapping.xsd"&gt;

  &lt;stream name="employeeFile" format="<span class="highlight">xml</span>"&gt;
    &lt;record name="employee" class="org.beanio.example.Employee"&gt;
      &lt;field name="firstName" /&gt;
      &lt;field name="lastName" /&gt;
      &lt;field name="title" /&gt;
      &lt;field name="salary" /&gt;
      &lt;field name="hireDate" <span class="highlight">type="date"</span> /&gt;
    &lt;/record&gt;
  &lt;/stream&gt;
&lt;/beanio&gt;</pre>

<p>That's it!  No Java code changes are required, and as before, <tt>Employee</tt> bean objects
will be unmarshalled from the XML input stream each time <tt>beanReader.read()</tt> is called.</p>
<p>And also as before, <tt>Employee</tt> objects can be marshalled to an XML output stream using 
<tt>beanWriter.write(Object)</tt>.  However, please note that when marshalling/writing XML, 
it is even more important to call <tt>beanWriter.close()</tt> so that the XML document can be 
properly completed.</p>


<h3><a name="XmlValidation">5.1.2. A Note on XML Validation</a></h3>
<p>Because BeanIO is built like a pull parser, it does not support XML validation against a DTD
or XML schema.  Where this functionality is needed, it is recommended to make two passes on the
input document.  The first pass can use a SAX parser or other means to validate the XML, and the
second pass can use BeanIO to parse and process bean objects read from the document.</p>


<h2><a name="XmlNames">5.2. XML Names</a></h2>
<p>Each BeanIO mapping element (stream, group, record, bean and field), is mapped to an XML
element with the same local name.  When the name of the stream, group, etc. does not match the XML
element name, the <tt>xmlName</tt> attribute can be used.  For example, if the name of the root element in the previous
example's employee file is changed from "employeeFile" to "employees", and "title" was renamed "position",
the mapping file could be updated as shown below.</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="employeeFile" format="xml" <span class="highlight">xmlName="employees"</span>&gt;
    &lt;record name="employee" class="org.beanio.example.Employee"&gt;
      &lt;field name="firstName" /&gt;
      &lt;field name="lastName" /&gt;
      &lt;field name="title" <span class="highlight">xmlName="position"</span> /&gt;
      &lt;field name="salary" /&gt;
      &lt;field name="hireDate" type="date" /&gt;
    &lt;/record&gt;
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>

<h2><a name="XmlNamespaces">5.3. XML Namespaces</a></h2>
<p>XML namespaces can be enabled by declaring namespaces using a <tt>xmlNamespace</tt> attribute
on any mapping element (stream, group, record, bean or field).  By default, all mapping elements 
inherit their namespace (or lack thereof) from their parent.  When a namespace is delcared, the local
name <i>and</i> namespace must match when unmarshalling XML, and appropriate namespace declarations
are included when marshalling bean objects.  For example, let's suppose our employee file contains
namespaces as shown below.</p>
<pre class="file">
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;employeeFile xmlns="http://example.com/employeeFile" xmlns:n="http://example.com/name"&gt;
  &lt;e:employee xmlns:e="http://example.com/employee"&gt;
    &lt;n:firstName&gt;Joe&lt;/n:firstName&gt;
    &lt;n:lastName&gt;Smith&lt;/n:lastName&gt;
    &lt;e:title&gt;Developer&lt;/e:title&gt;
    &lt;e:salary&gt;75000&lt;/e:salary&gt;
    &lt;e:hireDate&gt;2009-10-12&lt;/e:hireDate&gt;
  &lt;/e:employee&gt;
  .
  .
  .
&lt;/employeeFile&gt;
</pre>

<p>To unmarshall the file using namespaces, and to marshall Employee bean objects in the same fashion
as they appear above, the following mapping file can be used.</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="employeeFile" format="xml" <span class="highlight">xmlNamespace="http://example.com/employeeFile"</span>&gt;
    &lt;writer&gt;
      <span class="highlight">&lt;property name="namespaces" value="n http://example.com/name"/&gt;</span>
    &lt;/writer&gt;
    &lt;record name="employee" class="org.beanio.example.Employee" 
      <span class="highlight">xmlNamespace="http://example.com/employee"</span> <span class="highlight">xmlPrefix="e"</span>&gt;
      &lt;field name="firstName" <span class="highlight">xmlNamespace="http://example.com/name"</span> /&gt;
      &lt;field name="lastName" <span class="highlight">xmlNamespace="http://example.com/name"</span> /&gt;
      &lt;field name="title" /&gt;
      &lt;field name="salary" /&gt;
      &lt;field name="hireDate" type="date" /&gt;
    &lt;/record&gt;
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>

<p>From this example, the following behavior can be observed:</p>
<ul>
<li>An <tt>xmlPrefix</tt> attribute can be used to assign a namespace prefix anywhere a <tt>xmlNamespace</tt> is declared.  
 <ul>
 <li>If a prefix is configured, the namespace is assigned to the prefix and the prefix is used
   from that point forward.  This can be seen on the 'employee' element (<tt>record</tt> configuration).</li>
 <li>If a prefix is not configured, a namespace declaration will replace the default namespace.  This can
   be seen on the 'employeeFile' element (<tt>stream</tt> configuration).</li>
 </ul>
</li>
<li>As previously mentioned, namespace are by default inherited from parent mapping elements.  This
  can be seen on the 'title', 'salary' and 'hireDate' elements (<tt>field</tt> configurations).</li>
<li>Namespaces can be eagerly declared on the root element using the writer's <tt>namespaces</tt> property.
  Multiple namespaces can be declared with space delimiters such as '<i>prefix1 namespace1 prefix2 namespace2...</i>'.
</li>
</ul>

<p>BeanIO also supports a special wildcard namespace.  If <tt>xmlNamespace</tt> is set to '*', any namespace
is allowed when unmarshalling XML, and no namespace declaration will be made when marshalling XML.</p>

<p>The following table summarizes namespace configuration options and their effect on the configured
element and a child that inherits it's parent namespace.</p>
<table class="indent">
<tr>
  <th>Mapping Configuration</th>
  <th>Marshalled Element And Child</th>
</tr>
<tr>
  <td><pre>[None]</pre></td>
  <td><pre>&lt;element&gt;
  &lt;child/&gt;
&lt;/element&gt;</pre></td>
</tr>
<tr>
  <td><pre>xmlNamespace="*"</pre></td>
  <td><pre>&lt;element&gt;
  &lt;child/&gt;
&lt;/element&gt;</pre></td>
</tr>
<tr>
  <td><pre>xmlNamespace=""</pre></td>
  <td><pre>&lt;element xmlns=""&gt;
  &lt;child/&gt;
&lt;/element&gt;</pre></td>
</tr>
<tr>
  <td><pre>xmlNamespace="http://example.com"</pre></td>
  <td><pre>&lt;element xmlns="http://example.com"&gt;
  &lt;child/&gt;
&lt;/element&gt;</pre></td>
</tr>
<tr>
  <td><pre>xmlNamespace="http://example.com" xmlPrefix="e"</pre></td>
  <td><pre>&lt;e:element xmlns="http://example.com"&gt;
  &lt;e:child/&gt;
&lt;/e:element&gt;</pre></td>
</tr>
</table>

<h2><a name="XmlStreams">5.4. Stream Definitions for XML</a></h2>
<p>When unmarshalling multiple records from an XML document, the <tt>stream</tt> configuration 
is mapped to the root element in the XML formatted stream.  This default behavior has been 
demonstrated in previous examples.  If on the other hand, an XML document contains only a
single record, the document can be fully read or written by setting the <tt>stream</tt>
configuration's <tt>xmlType</tt> attribute to <tt>none</tt>.  This behavior is similar to
other OXM libraries that marshall or unmarshall one bean object per XML document.</p>

<p>For example, if BeanIO was used to unmarshall a single employee record submitted via a web
service, the XML document might look like the following.  Notice there is no 'employeeFile'
root element for containing multiple employee records.</p>
<pre class="file">
&lt;employee&gt;
  &lt;firstName&gt;Joe&lt;/firstName&gt;
  &lt;lastName&gt;Smith&lt;/lastName&gt;
  &lt;title&gt;Developer&lt;/title&gt;
  &lt;salary&gt;75000&lt;/salary&gt;
  &lt;hireDate&gt;2009-10-12&lt;/hireDate&gt;
&lt;/employee&gt;
</pre>

<p>In this example, the following highlighted changes can be made to our mapping file to
allow BeanIO to unmarshall/marshall a single employee record.</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="employeeFile" format="xml" <span class="highlight">xmlType="none"</span>&gt;
    &lt;record name="employee" class="org.beanio.example.Employee"&gt;
      &lt;field name="firstName" /&gt;
      &lt;field name="lastName" /&gt;
      &lt;field name="title" /&gt;
      &lt;field name="salary" /&gt;
      &lt;field name="hireDate" type="date" /&gt;
    &lt;/record&gt;
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>

<h2><a name="XmlGroups">5.5. Group Definitions for XML</a></h2>
<p>Like other mapping elements, groups are also mapped to XML elements by default.
Or if a group is used only for control purposes, the group's <tt>xmlType</tt> attribute
can be set to <tt>none</tt>.</p>

<h2><a name="XmlRecords">5.6. Record Definitions for XML</a></h2>
<p>A record is always mapped to an XML element.  As we've seen before, records are matched
based on their group context and configured record identifying fields.  XML records are further
matched using their XML element name, as defined
by <tt>xmlName</tt>, or if not present, <tt>name</tt>.  Other than record identifying fields,
fields and beans contained within the record are not used for matching.</p>

<p>For example, let's suppose our employee file differentiated managers using 'manager' tags.</p>
<pre class="file">
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;employeeFile&gt;
  &lt;employee&gt;
    &lt;firstName&gt;Joe&lt;/firstName&gt;
    &lt;lastName&gt;Smith&lt;/lastName&gt;
    &lt;title&gt;Developer&lt;/title&gt;
    &lt;salary&gt;75000&lt;/salary&gt;
    &lt;hireDate&gt;2009-10-12&lt;/hireDate&gt;
  &lt;/employee&gt;
  &lt;employee&gt;
    &lt;firstName&gt;Jane&lt;/firstName&gt;
    &lt;lastName&gt;Doe&lt;/lastName&gt;
    &lt;title&gt;Architect&lt;/title&gt;
    &lt;salary&gt;80000&lt;/salary&gt;
    &lt;hireDate&gt;2008-01-15&lt;/hireDate&gt;
  &lt;/employee&gt;
  &lt;manager&gt;
    &lt;firstName&gt;Jon&lt;/firstName&gt;
    &lt;lastName&gt;Andersen&lt;/lastName&gt;
    &lt;title&gt;Manager&lt;/title&gt;
    &lt;salary&gt;85000&lt;/salary&gt;
    &lt;hireDate&gt;2007-03-18&lt;/hireDate&gt;
  &lt;/manager&gt;
&lt;/employeeFile&gt;
</pre>

<p>To map managers to a new <tt>Manager</tt> bean we could use the following
mapping configuration.</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="employeeFile" format="xml"&gt;
    &lt;record name="employee" class="org.beanio.example.Employee"&gt;
      &lt;field name="firstName" /&gt;
      &lt;field name="lastName" /&gt;
      &lt;field name="title" /&gt;
      &lt;field name="salary" /&gt;
      &lt;field name="hireDate" type="date" /&gt;
    &lt;/record&gt;
    <span class="highlight">&lt;record name="manager" class="org.beanio.example.Manager"&gt;
      &lt;field name="firstName" /&gt;
      &lt;field name="lastName" /&gt;
      &lt;field name="title" /&gt;
      &lt;field name="salary" /&gt;
      &lt;field name="hireDate" type="date" /&gt;
    &lt;/record&gt;</span>
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>

<p>Do not forget BeanIO will enforce record order in this example unless <tt>ordered</tt>
is set to <tt>false</tt> on the stream, or unless each record is assigned the same order number.</p>


<h2><a name="XmlFields">5.7. Field Definitions for XML</a></h2>
<p>A field is mapped to XML using the field definition's <tt>xmlType</tt> attribute, which defaults to <tt>element</tt>.
The field XML type can be set to <tt>element</tt>, <tt>attribute</tt>, <tt>text</tt>, or <tt>none</tt>.  The following
table illustrates possible configurations, except for <tt>none</tt> which is not covered here.</p>

<table class="indent">
<tr>
  <th>Record Definition</th>
  <th>Sample Record</th>
</tr>
<tr>
  <td><pre>&lt;record name="person" class="map"&gt;
  &lt;field name="name" xmlType="element"/&gt;
&lt;/person&gt;</pre>
  </td>
  <td><pre>&lt;person&gt;
  &lt;name&gt;John&lt;/name&gt;
&lt;/person&gt;</pre>
</td>  
</tr>
<tr>
  <td><pre>&lt;record name="person" class="map"&gt;
  &lt;field name="name" xmlType="attribute"/&gt;
&lt;/person&gt;</pre>
  </td>
  <td><pre>&lt;person name="John"/&gt;</pre>
</td>  
</tr>
<tr>
  <td><pre>&lt;record name="person" class="map"&gt;
  &lt;field name="name" xmlType="text"/&gt;
&lt;/person&gt;</pre>
  </td>
  <td><pre>&lt;person&gt;John&lt;/person&gt;</pre>
</td>  
</tr>
</table>

<h3><a name="XmlTypeConversion">5.7.1. Field Type Conversion</a></h3>
<p>Field type conversion works the same way for XML formatted streams as it does for other formats.  However,
several default type handlers are overridden specifically for XML formatted streams to
conform with W3C XML Schema built-in data types according to this 
<a href="http://www.w3.org/TR/xmlschema-2/">specification</a>.
The following table summarizes overriden type handlers:</p>
<table class="indent">
<tr>
  <th>Class or Type Alias</th>
  <th>XML Schema Data Type</th>
  <th>Example</th>
</tr>
<tr>
  <td><tt>date</tt></td>
  <td><a href="http://www.w3.org/TR/xmlschema-2/#date">date</a></td>
  <td><tt>2011-01-01</tt></td>
</tr>
<tr>
  <td><tt>datetime</tt> or java.util.Date</td>
  <td><a href="http://www.w3.org/TR/xmlschema-2/#dateTime">dateTime</a></td>
  <td><tt>2011-01-01T15:14:13</tt></td>
</tr>
<tr>
  <td><tt>time</tt></td>
  <td><a href="http://www.w3.org/TR/xmlschema-2/#time">time</a></td>
  <td><tt>15:14:13</tt></td>
</tr>
<tr>
  <td><tt>boolean</tt></td>
  <td><a href="http://www.w3.org/TR/xmlschema-2/#boolean">boolean</a></td>
  <td><tt>true</tt></td>
</tr>
</table>

<p>Like other type handlers, XML specific type handlers can be customized or completely
replaced.  Please consult BeanIO javadocs for customization details.</p>

<h3><a name="NullFields">5.7.2. Marshalling Null Field Values</a></h3>
<p>The <tt>nillable</tt> and <tt>minOccurs</tt> field attributes control how a null field value is marshalled.  
If <tt>minOccurs</tt> is 0, an element or attribute is not marshalled for the field.
If an element type field has <tt>nillable</tt> set to <tt>true</tt> and <tt>minOccurs</tt> set to 1, the W3C XML Schema 
Instance attribute <tt>nil</tt> is set to <tt>true</tt>.</p>

<p>This behavior is illustrated in the following table.</p>
<table class="indent">
<tr>
  <th>Record Definition</th>
  <th>Marshalled Record<br/>(Field Value is Null)</th>
</tr>
<tr>
  <td><pre>&lt;record name="person" class="map"&gt;
  &lt;field name="name" xmlType="element" /&gt;
&lt;/person&gt;</pre>
  </td>
  <td><pre>&lt;person/&gt;</pre>
</td>
</tr>
<tr>
  <td><pre>&lt;record name="person" class="map"&gt;
  &lt;field name="name" xmlType="element" minOccurs="1" /&gt;
&lt;/person&gt;</pre>
  </td>
  <td><pre>&lt;person&gt;
  &lt;name/&gt;
&lt;/person&gt;</pre>
</td>
</tr>
<tr>
  <td><pre>&lt;record name="person" class="map"&gt;
  &lt;field name="name" xmlType="element" minOccurs="1" nillable="true"/&gt;
&lt;/person&gt;</pre>
  </td>
  <td><pre>&lt;person&gt;
  &lt;name xsi:nil="true"/&gt;
&lt;/person&gt;</pre>
</td>
</tr>
<tr>
  <td><pre>&lt;record name="person" class="map"&gt;
  &lt;field name="name" xmlType="attribute"/&gt;
&lt;/person&gt;</pre>
  </td>
  <td><pre>&lt;person/&gt;</pre>
</td>  
</tr>
<tr>
  <td><pre>&lt;record name="person" class="map"&gt;
  &lt;field name="name" xmlType="attribute" minOccurs="1"/&gt;
&lt;/person&gt;</pre>
  </td>
  <td><pre>&lt;person name=""/&gt;</pre>
</td>  
</tr>
<tr>
  <td><pre>&lt;record name="person" class="map"&gt;
  &lt;field name="name" xmlType="text"/&gt;
&lt;/person&gt;</pre>
  </td>
  <td><pre>&lt;person/&gt;</pre>
</td>  
</tr>
</table>

<h2><a name="XmlBeans">5.8. Bean Definitions for XML</a></h2>
<p>Nested bean definitions can be mapped to XML elements or used to
group fields.  This difference can be explored using the Address and Employee
beans defined in Section 4.4 and repeated here.</p>
<pre class="java">
package org.beanio.example;

public class Address {
    String street;
    String city;
    String state;
    String zip;
    
    <span class="comment">// getters and setters not shown...</span>
}</pre>
<pre class="java">
package org.beanio.example;
import java.util.Date;

public class Employee {
    String firstName;
    String lastName;
    String title;
    int salary;
    Date hireDate;
    Address mailingAddress;
    
    <span class="comment">// getters and setters not shown...</span>
}</pre>

<p>By default, a bean definition's <tt>xmlType</tt> is set to <tt>element</tt>, so
it is not necessary to declare it in the mapping file below.</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="employeeFile" format="xml"&gt;
    &lt;record name="employee" class="org.beanio.example.Employee"&gt;
      &lt;field name="firstName" /&gt;
      &lt;field name="lastName" /&gt;
      &lt;field name="title" /&gt;
      &lt;field name="salary" /&gt;
      &lt;field name="hireDate" type="date" /&gt;
      &lt;bean name="mailingAddress" class="org.beanio.example.Address" <span class="highlight">xmlType="element"</span>&gt;
        &lt;field name="street" /&gt;
        &lt;field name="city" /&gt;
        &lt;field name="state" /&gt;      
        &lt;field name="zip" /&gt;
      &lt;/bean&gt;
    &lt;/record&gt; 
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>

<p>This mapping configuration can be used to process the sample XML document below.  When
a bean is mapped to an XML element, <tt>nillable</tt> and <tt>minOccurs</tt> will control
the marshalling behavior of null bean objects in the same fashion as a field (see <a href="#NullFields">Section 5.7.2</a>).
</p>
<pre class="file">
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;employeeFile&gt;
  &lt;employee&gt;
    &lt;firstName&gt;Joe&lt;/firstName&gt;
    &lt;lastName&gt;Smith&lt;/lastName&gt;
    &lt;title&gt;Developer&lt;/title&gt;
    &lt;salary&gt;75000&lt;/salary&gt;
    &lt;hireDate&gt;2009-10-12&lt;/hireDate&gt;
    &lt;mailingAddress&gt;
      &lt;street&gt;123 Main Street&lt;/street&gt;
      &lt;city&gt;Chicago&lt;/city&gt;
      &lt;state&gt;IL&lt;/state&gt;
      &lt;zip&gt;12345&lt;/zip&gt;
    &lt;/mailingAddress&gt;
  &lt;/employee&gt;
  .
  .
  .
&lt;/employeeFile&gt;
</pre>

<p>Alternatively, if the bean definition's <tt>xmlType</tt> is set to <tt>none</tt>,
the following XML document can be processed.</p>
<pre class="file">
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;employeeFile&gt;
  &lt;employee&gt;
    &lt;firstName&gt;Joe&lt;/firstName&gt;
    &lt;lastName&gt;Smith&lt;/lastName&gt;
    &lt;title&gt;Developer&lt;/title&gt;
    &lt;salary&gt;75000&lt;/salary&gt;
    &lt;hireDate&gt;2009-10-12&lt;/hireDate&gt;
    &lt;street&gt;123 Main Street&lt;/street&gt;
    &lt;city&gt;Chicago&lt;/city&gt;
    &lt;state&gt;IL&lt;/state&gt;
    &lt;zip&gt;12345&lt;/zip&gt;
  &lt;/employee&gt;
  .
  .
  .
&lt;/employeeFile&gt;
</pre>

<h2><a name="XmlWrappers">5.9. XML Wrappers</a></h2>
<p>In some cases, an XML document may contain elements that do not map directly
to a bean or field.  In these situations, the <tt>xmlWrapper</tt> attribute may help.
The <tt>xmlWrapper</tt> attribute is used to configure the local name of an XML element
that wraps a record, bean or field.  The wrapper element uses the same namespace
as the element (record, bean or field) for which it was configured.</p>

<p>Extending the previous example, let's suppose the <tt>Employee</tt> bean object is modified
to hold a list of addresses.</p>
<pre class="java">
package org.beanio.example;
import java.util.Date;

public class Employee {
    String firstName;
    String lastName;
    String title;
    int salary;
    Date hireDate;
    List&lt;Address&gt; addressList;
    
    <span class="comment">// getters and setters not shown...</span>
}</pre>

<p>And let's further suppose that each employee's list of addresses is enclosed in a new element called
<tt>addresses</tt>.</p>
<pre class="file">
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;employeeFile&gt;
  &lt;employee&gt;
    &lt;firstName&gt;Joe&lt;/firstName&gt;
    &lt;lastName&gt;Smith&lt;/lastName&gt;
    &lt;title&gt;Developer&lt;/title&gt;
    &lt;salary&gt;75000&lt;/salary&gt;
    &lt;hireDate&gt;2009-10-12&lt;/hireDate&gt;
    &lt;addresses&gt;
      &lt;mailingAddress&gt;
        &lt;street&gt;123 Main Street&lt;/street&gt;
        &lt;city&gt;Chicago&lt;/city&gt;
        &lt;state&gt;IL&lt;/state&gt;
        &lt;zip&gt;12345&lt;/zip&gt;
      &lt;/mailingAddress&gt;
    &lt;/addresses&gt;
  &lt;/employee&gt;
  .
  .
  .
&lt;/employeeFile&gt;
</pre>

<p>The mapping file can now be updated as follows:</p>
<pre class="file">
&lt;beanio&gt;

  &lt;stream name="employeeFile" format="xml"&gt;
    &lt;record name="employee" class="org.beanio.example.Employee"&gt;
      &lt;field name="firstName" /&gt;
      &lt;field name="lastName" /&gt;
      &lt;field name="title" /&gt;
      &lt;field name="salary" /&gt;
      &lt;field name="hireDate" type="date" /&gt;
      &lt;bean name="mailingAddress" class="org.beanio.example.Address" collection="list" 
        minOccurs="0" maxOccurs="unbounded" <span class="highlight">xmlWrapper="addresses"</span>&gt;
        &lt;field name="street" /&gt;
        &lt;field name="city" /&gt;
        &lt;field name="state" /&gt;      
        &lt;field name="zip" /&gt;
      &lt;/bean&gt;
    &lt;/record&gt; 
  &lt;/stream&gt;
  
&lt;/beanio&gt;</pre>

<p>The following table illustrates different <tt>xmlWrapper</tt> effects based on the <tt>xmlType</tt>
of a field, and the effect of <tt>minOccurs</tt> and <tt>nillable</tt> when marshalling null field values.</p>

<table class="indent">
<tr>
  <th>Record Definition</th>
  <th>Non-Null Field Value</th>
  <th>Null Field Value</th>
</tr>
<tr>
  <td><pre>&lt;field name="field" 
  xmlType="element" 
  xmlWrapper="wrapper" 
  minOccurs="0" /&gt;</pre>
  </td>
  <td rowspan="3"><pre>&lt;wrapper&gt;
  &lt;field&gt;value&lt;/field&gt;
&lt;/wrapper&gt;</pre>
</td>
  <td>-</td>
</tr>
<tr>
  <td><pre>&lt;field name="field" 
  xmlType="element" 
  xmlWrapper="wrapper" 
  minOccurs="1"
  nillable="true" /&gt;</pre>
  </td>
  <td><pre>&lt;wrapper&gt;
  &lt;field xsi:nil="true"/&gt;
&lt;/wrapper&gt;</pre>
</td>
</tr>
<tr>
  <td><pre>&lt;field name="field" 
  xmlType="element" 
  xmlWrapper="wrapper" 
  minOccurs="1" /&gt;</pre>
  </td>
  <td><pre>&lt;wrapper&gt;
  &lt;field/&gt;
&lt;/wrapper&gt;</pre>
</td>
</tr>


<tr>
  <td><pre>&lt;field name="field" 
  xmlType="attribute" 
  xmlWrapper="wrapper" 
  minOccurs="0" /&gt;</pre>
  </td>
  <td rowspan="2"><pre>&lt;wrapper field="value"/&gt;</pre>
</td>
  <td>-</td>
</tr>
<tr>
  <td><pre>&lt;field name="field" 
  xmlType="attribute" 
  xmlWrapper="wrapper" 
  minOccurs="1" /&gt;</pre>
  </td>
  <td><pre>&lt;wrapper field=""/&gt;</pre></td>
</tr>

<tr>
  <td><pre>&lt;field name="field" 
  xmlType="text"
  xmlWrapper="wrapper" 
  minOccurs="1" /&gt;</pre>
  </td>
  <td rowspan="3"><pre>&lt;wrapper&gt;value&lt;/wrapper&gt;</pre>
</td>
  <td><pre>&lt;wrapper /&gt;</pre>
</td>
</tr>
<tr>
  <td><pre>&lt;field name="field" 
  xmlType="text" 
  xmlWrapper="wrapper" 
  minOccurs="1"
  nillable="true" /&gt;</pre>
  </td>
  <td><pre>&lt;wrapper xsi:nil="true"/&gt;</pre>
</td>
</tr>
<tr>
  <td><pre>&lt;field name="field" 
  xmlType="text" 
  xmlWrapper="wrapper" 
  minOccurs="0" /&gt;</pre>
  </td>
  <td>-</td>
</tr>
</table>
<p>Wrapped collection fields (and beans) behave a little differently depending on whether the collection
is null or empty.</p>
<table class="indent">
<tr>
  <th>Record Definition</th>
  <th>Collection</th>
  <th>Null Collection</th>
  <th>Empty Collection</th>
</tr>
<tr>
  <td><pre>&lt;field name="field" 
  collection="list"
  minOccurs="0"
  xmlType="element" 
  xmlWrapper="wrapper" /&gt;</pre>
  </td>
  <td rowspan="3"><pre>&lt;wrapper&gt;
  &lt;field&gt;value1&lt;/field&gt;
  &lt;field&gt;value2&lt;/field&gt;  
&lt;/wrapper&gt;</pre>
</td>
  <td><pre>-</pre></td>
  <td><pre>&lt;wrapper /&gt;</pre>
</td>
</tr>
<tr>
  <td><pre>&lt;field name="field" 
  collection="list"
  minOccurs="0"
  xmlType="element" 
  xmlWrapper="wrapper" 
  nillable="true" /&gt;</pre>
  </td>
  <td><pre>-</pre></td>
  <td><pre>&lt;wrapper xsi:nil="true"/&gt;</pre>
</td>
</tr>
<tr>
  <td><pre>&lt;field name="field" 
  collection="list"
  minOccurs="1"
  xmlType="element" 
  xmlWrapper="wrapper" 
  nillable="false" /&gt;</pre>
  </td>
  <td><pre>&lt;wrapper&gt;
  &lt;field/&gt;
&lt;/wrapper&gt;</pre>
</td>
  <td><pre>&lt;wrapper&gt;
  &lt;field/&gt;
&lt;/wrapper&gt;</pre>
</td>
</tr>
</table>


<!-- 

	SPRING BATCH

 -->
<h1><a name="SpringBatch">6.0. Spring Batch Integration</a></h1>
<p>As of release 1.2, BeanIO can be used to read and write flat files with 
<a href="http://static.springsource.org/spring-batch/">Spring Batch</a> (2.1.x), 
a batch processing framework by SpringSource.</p>

<h2><a name="SpringItemReaderWriter">6.1. BeanIO ItemReader/Writer Beans</a></h2>
<p>The class <tt>org.beanio.spring.BeanIOFlatFileItemReader</tt> implements Spring Batch's
<tt>ItemReader</tt> interface and can be used to read flat files using a BeanIO stream
mapping file.  The following Spring bean definition shows a BeanIO item reader configuration
that loads a BeanIO mapping file called 'mapping.xml' from the classpath to read a file
called 'in.txt'.  The location of the mapping file is set using the <tt>streamMapping</tt>
property, and the name of the stream layout is specified using the <tt>streamName</tt>
property.</p>
<pre class="file">
  &lt;bean id="itemReader" class="org.beanio.spring.BeanIOFlatFileItemReader"&gt;
    &lt;property name="streamMapping" value="classpath:/mapping.xml" /&gt;
    &lt;property name="streamName" value="stream" /&gt;
    &lt;property name="resource" value="file:in.txt" /&gt;
  &lt;/bean&gt;</pre>

<p>Similarly, the class <tt>org.beanio.spring.BeanIOFlatFileItemWriter</tt> implements Spring Batch's
<tt>ItemWriter</tt> interface and can be used to write flat files using a BeanIO stream
mapping file.  The following Spring bean definition shows a BeanIO item writer configuration
that loads a BeanIO mapping file called 'mapping.xml' from the classpath to write a file
called 'out.txt'.</p>
<pre class="file">
  &lt;bean id="itemWriter" class="org.beanio.spring.BeanIOFlatFileItemWriter"&gt;
    &lt;property name="streamMapping" value="classpath:/mapping.xml" /&gt;
    &lt;property name="streamName" value="stream" /&gt;
    &lt;property name="resource" value="file:out.txt" /&gt;
  &lt;/bean&gt;</pre>

<p>BeanIO item readers and writers are restartable, and support many of the same properties supported
by the flat file item reader and writer included with Spring Batch.  Please refer to their 
<a href="http://www.beanio.org/docs/api/index.html">API documentation</a> for details.</p>

<h2><a name="SpringStreamFactory">6.2. BeanIO StreamFactory Bean</a></h2>
<p>By default, a BeanIO item reader/writer creates its own stream factory, but
in cases where this could cause one or more mapping files to be loaded multiple times, it may be preferable 
to create a shared stream factory instance.  BeanIO's <tt>org.beanio.spring.BeanIOStreamFactory</tt> class
can be used to create a shared stream factory that can be injected into BeanIO item readers and writers.
The following Spring beans configuration file illustrates this:</p>

<pre class="file">
&lt;beans&gt;

  <span class="highlight">&lt;bean id="streamFactory" class="org.beanio.spring.BeanIOStreamFactory"&gt;
    &lt;property name="streamMappings"&gt;
      &lt;list&gt;
        &lt;value&gt;classpath:/mapping1.xml&lt;/value&gt;
        &lt;value&gt;file:/mapping2.xml&lt;/value&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/bean&gt;</span>
  
  &lt;bean id="itemReader" class="org.beanio.spring.BeanIOFlatFileItemReader"&gt;
    <span class="highlight">&lt;property name="streamFactory" ref="streamFactory" /&gt;</span>
    &lt;property name="streamName" value="stream" /&gt;
    &lt;property name="resource" value="file:in.txt" /&gt;
  &lt;/bean&gt;
  
&lt;/beans&gt;</pre>


<h1><a name="Configuration">7.0. Configuration</a></h1>
<p>In some cases, BeanIO behavior can be controlled by setting optional property values.  Properties
can be set using System properties or a property file.  BeanIO will load configuration
setting in the following order of priority:</p>
<ol>
<li>System properties.</li>
<li>A property file named <tt>beanio.properties</tt>.  The file will be looked for first in the application's
  working directory, and then on the classpath.</li>
</ol>
<p>The name and location of <tt>beanio.properties</tt> can be overridden using the System
property <tt>org.beanio.configuration</tt>.  In the following example, configuration settings will 
be loaded from the file named <tt>config/settings.properties</tt>, first relative to the application's
working directory, and if not found, then from the root of the application's classpath.</p>
<pre class="indent">java <span class="highlight">-Dorg.beanio.configuration=config/settings.properties</span> org.beanio.example.Main</pre>

<h2><a name="ConfigurationSettings">7.1. Settings</a></h2>
<p>The following configuration settings are supported by BeanIO:</p>
<table class="indent">
<tr>
  <th>Property</th>
  <th>Description</th>
  <th>Default</th>
</tr>
<tr>
  <td><tt>org.beanio.propertyEscapingEnabled</tt></td>
  <td>Whether <a href="#property"><tt>property</tt></a> values (for <tt>typeHandler</tt>, <tt>reader</tt> 
    and <tt>writer</tt> elements) support escape patterns for line feeds, carriage returns, tabs, etc.  
    Set to <tt>true</tt> or <tt>false</tt>.</td>
  <td><tt>true</tt></td>
</tr>
<tr>
  <td><tt>org.beanio.marshalDefaultEnabled</tt></td>
  <td>Whether a configured <a href="#field"><tt>field</tt></a> default is marshalled for null property values.
    May be disabled for backwards compatibility by setting the value to <tt>false</tt>.
    </td>
  <td><tt>true</tt></td>
</tr>
<tr>
  <td><tt>org.beanio.defaultDateFormat</tt></td>
  <td>Sets the default <tt>SimpleDateFormat</tt> pattern for <tt>date</tt> type fields in
    CSV, delimited and fixed length file formats.</td>
  <td><tt>DateFormat. getDateInstance()</tt></td>
</tr>
<tr>
  <td><tt>org.beanio.defaultDateTimeFormat</tt></td>
  <td>Sets the default <tt>SimpleDateFormat</tt> pattern for <tt>datetime</tt> type fields in
    CSV, delimited and fixed length file formats..</td>
  <td><tt>DateFormat. getDateTimeInstance()</tt></td>
</tr>
<tr>
  <td><tt>org.beanio.defaultTimeFormat</tt></td>
  <td>Sets the default <tt>SimpleDateFormat</tt> pattern for <tt>time</tt> type fields in
    CSV, delimited and fixed length file formats..</td>
  <td><tt>DateFormat. getTimeInstance()</tt></td>
</tr>
<tr>
  <td><tt>org.beanio.xml.defaultXmlType</tt></td>
  <td>Sets the default XML type for a field in an XML formatted stream.  May be set
    to <tt>element</tt> or <tt>attribute</tt>.</td>
  <td><tt>element</tt></td>
</tr>
<tr>
  <td><tt>org.beanio.xml.xsiNamespacePrefix</tt></td>
  <td>Sets the default prefix for the namespace <tt>http://www.w3.org/2001/XMLSchema-instance</tt>.</td>
  <td><tt>xsi</tt></td>
</tr>
</table>


<!-- 

	APPENDIX A
	
 -->
<h1><a name="A">Appendix A:  XML Mapping File Reference</a></h1>
<p>Appendix A is the complete reference for the BeanIO mapping file schema.  The root element
of a mapping file is <tt><a href="#beanio">beanio</a></tt> with namespace 
<tt>http://www.beanio.org/2011/01</tt>.  The following notatiion is used to indicate the
allowed number of child elements:
 </p>
<div style="margin-left: 5%">
	* Zero, one or more<br />
	+ One or more<br />
	? Zero or one<br />
</div>

<h2><a name="beanio">A.1. <tt>beanio</tt></a></h2>
<p>The <tt>beanio</tt> element is the root element for a BeanIO mapping configuration file.</p>
<p>Children:
<a href="#import"><tt>import</tt></a>*,
<a href="#typeHandler"><tt>typeHandler</tt></a>*,
<a href="#template"><tt>template</tt></a>*,
<a href="#stream"><tt>stream</tt></a>*
</p>

<h2><a name="import">A.2. <tt>import</tt></a></h2>
<p>The <tt>import</tt> element is used to import type handlers, templates and stream definitions
from an external mapping file.  Stream definitions declared in a mapping file being imported are 
not affected by global type handlers or templates declared in the file that imported it.</p> 
<p>Attributes:</p>
<table>
<tr>
  <th>Attribute</th>
  <th>Description</th>
  <th>Required</th>
</tr>
<tr>
  <td><tt>resource</tt></td>
  <td>The name of the resource to import.  
    <p>The resource name must be qualified with 'classpath:' to load the resource from 
    the classpath, or with 'file:' to load the file relative to the application's working 
    directory.</p></td>
  <td>Yes</td>
</tr>
</table>

<h2><a name="typeHandler">A.3. <tt>typeHandler</tt></a></h2>
<p>A <tt>typeHandler</tt> element is used to declare a custom field type handler
that implements the <a href="http://beanio.org/docs/api/org/beanio/types/TypeHandler.html">
<tt>org.beanio.types.TypeHandler</tt></a> interface.  A type handler
can be registered for a specific Java type, or registered for a Java type and stream format 
combination, or explicitly named.</p> 
<p>Attributes:</p>
<table>
<tr>
  <th>Attribute</th>
  <th>Description</th>
  <th>Required</th>
</tr>
<tr>
  <td><tt>name</tt></td>
  <td>The type handler name.  A <a href="#field">field</a> can always reference a type
    handler by name, even if the stream format does not match the
    configured type handler <tt>format</tt> attribute.
    <p>When configured, the name of a globally declared type handler must be unique
      within a mapping and any imported mapping files.</p></td>
  <td>One of <tt>name</tt> or <tt>type</tt> is required.</td>
</tr>
<tr>
  <td><tt>type</tt></td>
  <td>The fully qualified classname or type alias to register the type handler for.
    If <tt>format</tt> is also set, the type handler will only be used
    by streams that match the configured format.
    </td>
  <td>One of <tt>name</tt> or <tt>type</tt> is required.</td>
</tr>
<tr>
  <td><tt>class</tt></td>
  <td>The fully qualified classname of the <tt>TypeHandler</tt> implementation.</td>
  <td>Yes</td>
</tr>
<tr>
  <td><tt>format</tt></td>
  <td>When used in conjunction with the <tt>type</tt> attribute, a type handler can be
    registered for a specific stream format.  Set to <tt>xml</tt>, <tt>csv</tt>,
    <tt>delimited</tt>, or <tt>fixedlength</tt>.  If not set, the type handler may be
    used by any stream format.</td>
  <td>No</td>
</tr>
</table>

<p>Children: 
<a href="#property"><tt>property</tt></a>*
</p>

<h2><a name="property">A.4. <tt>property</tt></a></h2>
<p>A <tt>property</tt> element is used to customize other elements, such
as a <a href="#typeHandler"><tt>typeHandler</tt></a>, <a href="#reader"><tt>reader</tt></a>,
or <a href="#writer"><tt>writer</tt></a>.</p>
<table>
<tr>
  <th>Attribute</th>
  <th>Description</th>
  <th>Required</th>
</tr>
<tr>
  <td><tt>name</tt></td>
  <td>The property name.</td>
  <td>Yes</td>
</tr>
<tr>
  <td><tt>value</tt></td>
  <td>The property value.
    <p>When used to customize a <a href="#typeHandler"><tt>typeHandler</tt></a>, <a href="#reader"><tt>reader</tt></a>,
      or <a href="#writer"><tt>writer</tt></a>, default type handlers only are used to convert
      property text to an object value.  String and Character type property values can use the following escape
      sequences: <tt>\\</tt> (Backslash), <tt>\n</tt> (Line Feed), <tt>\r</tt> (Carriage Return), <tt>\t</tt> (Tab),
      and <tt>\f</tt> (Form Feed).  A backslash precending any other character is ignored.</p>
  </td>
  <td>Yes</td>
</tr>
</table>
<p>A <tt>property</tt> element, when used as child of a <a href="#record"><tt>record</tt></a> or 
<a href="#bean"><tt>bean</tt></a> element, can be used to set 
constant values on a record or bean object that do not map to a field in the input or output stream.  
The following additional attributes are accepted in this scenario:</p>
<p>Attributes:</p>
<table>
<tr>
  <th>Attribute</th>
  <th>Description</th>
  <th>Required</th>
  <th>Format(s)</th>
</tr>
<tr>
  <td><tt>getter</tt></td>
  <td>The getter method used to retrieve the property value from its parent bean class.
    By default, the getter method is determined through intropection using
    the property name.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>setter</tt></td>
  <td>The setter method used to set the property value on its parent bean class.  
    By default, the setter method is determined through intropection using
    the property name.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>rid</tt></td>
  <td>Record identifier indicator for marshalling/writing only.  Set to <tt>true</tt> if this property is 
    used to identify the record mapping configuration used to marshall a bean object.  
    More than one property or field can be used for identification.  Defaults to <tt>false</tt>.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>type</tt></td>
  <td>The fully qualified class name or type alias of the property value.  By default,
    BeanIO will derrive the property type from the bean class.  This attribute
    can be used to override the default or may be required if the bean class
    is of type <tt>Map</tt>.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>typeHandler</tt></td>
  <td>The name of the type handler to use for type conversion.  By default, BeanIO
    will select a type handler based on <tt>type</tt> when set, or through 
    introspection of the property's parent bean class.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>format</tt></td>
  <td>The decimal format pattern for <tt>Number</tt> type properties, or the simple
    date format pattern for <tt>Date</tt> type properties.
    <p>The <tt>format</tt> value can accessed by any custom type handler that
    implements <tt>ConfigurableTypeHandler</tt>.</p>  
  </td>
  <td>No</td>
  <td>*</td>
</tr>
</table>


<h2><a name="template">A.5. <tt>template</tt></a></h2>
<p>The <tt>template</tt> element is used to create reusable lists of bean properties.</p>
<p>Attributes:</p>
<table>
<tr>
  <th>Attribute</th>
  <th>Description</th>
  <th>Required</th>
</tr>
<tr>
  <td><tt>name</tt></td>
  <td>The name of the template.  Template names must be unique within a mapping file
    and any imported mapping files.</td>
  <td>Yes</td>
</tr>
</table>
<p>Children: 
( <a href="#field"><tt>field</tt></a> | 
<a href="#property"><tt>property</tt></a> |
<a href="#bean"><tt>bean</tt></a> |
<a href="#include"><tt>include</tt></a> )*
</p>

<h2><a name="include">A.6. <tt>include</tt></a></h2>
<p>The <tt>include</tt> element is used to include a template in a <a href="#record"><tt>record</tt></a>,
<a href="#bean"><tt>bean</tt></a>, or another <a href="#template"><tt>template</tt></a>.</p>
<p>Attributes:</p>
<table>
<tr>
  <th>Attribute</th>
  <th>Description</th>
  <th>Required</th>
</tr>
<tr>
  <td><tt>template</tt></td>
  <td>The name of the template to include.</td>
  <td>Yes</td>
</tr>
<tr>
  <td><tt>offset</tt></td>
  <td>The offset added to field positions included by the template.  Defaults to 0. </td>
  <td>No</td>
</tr>
</table>


<h2><a name="stream">A.7. <tt>stream</tt></a></h2>
<p>A <tt>stream</tt> element defines the record layout of an input or output stream.</p> 
<p>Attributes:</p>
<table>
<tr>
  <th>Attribute</th>
  <th>Description</th>
  <th>Required</th>
  <th>Format(s)</th>
</tr>
<tr>
  <td><tt>name</tt></td>
  <td>The name of the stream.</td>
  <td>Yes</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>format</tt></td>
  <td>The stream format.  Either <tt>xml</tt>, <tt>csv</tt>, <tt>delimited</tt> or
    <tt>fixedlength</tt></td>
  <td>Yes</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>mode</tt></td>
  <td>By default, a stream mapping can be used for both reading input streams and writing 
    output streams, called <tt>readwrite</tt> mode.  Setting mode to <tt>read</tt> or 
    <tt>write</tt> instead, respectively restricts usage to a <tt>BeanReader</tt> or a 
    <tt>BeanWriter</tt> only, but relaxes some validations on the mapping configuration.
    <p>When mode is set <tt>read</tt>, a bean class does not require getter methods. </p>
    <p>When mode is set <tt>write</tt>, a bean class may be abstract or an interface, and does
      not require setter methods.</p>
  </td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>resourceBundle</tt></td>
  <td>The name of the resource bundle for customizing error messages.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>ordered</tt></td>
  <td>When set to <tt>false</tt>, records may appear in any order, and specifying 
    a record <tt>order</tt> will cause a configuration error to be thrown.  
    Defaults to <tt>true</tt>.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>minOccurs</tt></td>
  <td>The minimum number of times the record layout must be read from an
    input stream.  Defaults to <tt>0</tt>.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>maxOccurs</tt></td>
  <td>The maximum number of times the record layout can repeat when read from an
    input stream.  Defaults to <tt>1</tt>.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>xmlType</tt></td>
  <td>The XML node type mapped to the stream.  
  If not specified or set to <tt>element</tt>, the stream is mapped to the root element of the
  XML document being marshalled or unmarshalled.  If set to <tt>none</tt>, the XML input stream 
  will be fully read and mapped to a group or record.</td>
  <td>No</td>
  <td>xml</td>
</tr>
<tr>
  <td><tt>xmlName</tt></td>
  <td>The local name of the XML element mapped to the stream.  Defaults to the stream name.</td>
  <td>No</td>
  <td>xml</td>
</tr>
<tr>
  <td><tt>xmlNamespace</tt></td>
  <td>The namespace of the XML element mapped to the stream.  Defaults to '*' which will ignore
    namespaces while marshalling and unmarshalling.</td>
  <td>No</td>
  <td>xml</td>
</tr>
<tr>
  <td><tt>xmlPrefix</tt></td>
  <td>The namespace prefix assigned to the declared <tt>xmlNamespace</tt> for marshalling XML.  
    If not specified, the default namespace (i.e. <tt>xmlns="..."</tt>) is used.</td>
  <td>No</td>
  <td>xml</td>
</tr>
</table>

<p>Children: 
<a href="#reader"><tt>reader</tt></a>?,
<a href="#writer"><tt>writer</tt></a>?,
<a href="#typeHandler"><tt>typeHandler</tt></a>*,
( <a href="#record"><tt>record</tt></a> |
<a href="#group"><tt>group</tt></a> )+
</p>

<h2><a name="reader">A.8. <tt>reader</tt></a></h2>
<p>A <tt>reader</tt> element is used to customize or replace the default record reader factory
for the stream..</p> 
<p>Attributes:</p>
<table>
<tr>
  <th>Attribute</th>
  <th>Description</th>
  <th>Required</th>
</tr>
<tr>
  <td><tt>class</tt></td>
  <td>The fully qualified class name of the <a href="../api/org/beanio/stream/RecordReaderFactory.html">
    <tt>org.beanio.stream.RecordReaderFactory</tt></a> implementation
    to use for this stream.  If not specified, one of the following default factories is 
    used based on the stream format:<br />
    <br />csv - <a href="../api/org/beanio/stream/csv/CsvReaderFactory.html"><tt>org.beanio.stream.csv.CsvReaderFactory</tt></a>
    <br />delimited - <a href="../api/org/beanio/stream/delimited/DelimitedReaderFactory.html"><tt>org.beanio.stream.delimited.DelimitedReaderFactory</tt></a>
    <br />fixedlength - <a href="../api/org/beanio/stream/fixedlength/FixedLengthReaderFactory.html"><tt>org.beanio.stream.fixedlength.FixedLengthReaderFactory</tt></a>
    <br />xml - <a href="../api/org/beanio/stream/xml/XmlReaderFactory.html"><tt>org.beanio.stream.xml.XmlReaderFactory</tt></a>
    <p>Overriding the record reader factory for XML is not supported.</p>
  </td>
  <td>No</td>
</tr>
</table>

<p>Children: 
<a href="#property"><tt>property</tt></a>*
</p>

<h2><a name="writer">A.9. <tt>writer</tt></a></h2>
<p>A <tt>writer</tt> element is used to customize or replace the default record writer factory
for the stream..</p> 
<p>Attributes:</p>
<table>
<tr>
  <th>Attribute</th>
  <th>Description</th>
  <th>Required</th>
</tr>
<tr>
  <td><tt>class</tt></td>
  <td>The fully qualified class name of the <a href="../api/org/beanio/stream/RecordWriterFactory.html">
    <tt>org.beanio.stream.RecordWriterFactory</tt></a> implementation
    to use for this stream.  If not specified, one of the following default factories is 
    used based on the stream format:<br />
    <br />csv - <a href="../api/org/beanio/stream/csv/CsvWriterFactory.html"><tt>org.beanio.stream.csv.CsvWriterFactory</tt></a>
    <br />delimited - <a href="../api/org/beanio/stream/delimited/DelimitedWriterFactory.html"><tt>org.beanio.stream.delimited.DelimitedWriterFactory</tt></a>
    <br />fixedlength - <a href="../api/org/beanio/stream/fixedlength/FixedLengthWriterFactory.html"><tt>org.beanio.stream.fixedlength.FixedLengthWriterFactory</tt></a>
    <br />xml - <a href="../api/org/beanio/stream/xml/XmlWriterFactory.html"><tt>org.beanio.stream.xml.XmlWriterFactory</tt></a>
    <p>Overriding the record writer factory for XML is not supported.</p>
  </td>
  <td>No</td>
</tr>
</table>

<p>Children: 
<a href="#property"><tt>property</tt></a>*
</p>

<h2><a name="group">A.10. <tt>group</tt></a></h2>
<p>A <tt>group</tt> element is used to group records together for validating occurrences of
the group as a whole.</p> 
<p>Attributes:</p>
<table>
<tr>
  <th>Attribute</th>
  <th>Description</th>
  <th>Required</th>
  <th>Format(s)</th>
</tr>
<tr>
  <td><tt>name</tt></td>
  <td>The name of the group.</td>
  <td>Yes</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>order</tt></td>
  <td>The order this group must appear within its parent group or stream.  Unless the stream
    is unordered, <tt>order</tt> will default to the next sequential number following the 
    order of the previous record/group at the same level.  If this is the first record/group, 
    <tt>order</tt> defaults to <tt>1</tt>.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>minOccurs</tt></td>
  <td>The minimum number of occurences of this group within its parent group or stream.
    Defaults to 1.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>maxOccurs</tt></td>
  <td>The maximum number of occurences of this group within its parent group or stream.
    Defaults to <tt>unbounded</tt>.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>xmlType</tt></td>
  <td>The XML node type mapped to this group.  
  If not specified or set to <tt>element</tt>, this group is mapped to an XML element.  When set to 
  <tt>none</tt>, this group is used only to define expected record sequencing.</td>
  <td>No</td>
  <td>xml</td>
</tr>
<tr>
  <td><tt>xmlName</tt></td>
  <td>The local name of the XML element mapped to this group.  Defaults to the group name.</td>
  <td>No</td>
  <td>xml</td>
</tr>
<tr>
  <td><tt>xmlNamespace</tt></td>
  <td>The namespace of the XML element mapped to this group.  Defaults to the namespace declared for the
    parent stream or group definition.</td>
  <td>No</td>
  <td>xml</td>
</tr>
<tr>
  <td><tt>xmlPrefix</tt></td>
  <td>The namespace prefix assigned to the declared <tt>xmlNamespace</tt> for marshalling XML.  
    If not specified, the default namespace (i.e. <tt>xmlns="..."</tt>) is used.</td>
  <td>No</td>
  <td>xml</td>
</tr>
</table>

<p>Children: 
<a href="#record"><tt>record</tt></a>*
</p>

<h2><a name="record">A.11. <tt>record</tt></a></h2>
<p>A <tt>record</tt> is used to define a record mapping within a stream.</p> 
<p>Attributes:</p>
<table>
<tr>
  <th>Attribute</th>
  <th>Description</th>
  <th>Required</th>
  <th>Format(s)</th>
</tr>
<tr>
  <td><tt>name</tt></td>
  <td>The name of the record.</td>
  <td>Yes</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>order</tt></td>
  <td>The order this record must appear within its parent group or stream.  Unless the stream
    is unordered, <tt>order</tt> will default to the next sequential number following the 
    order of the previous record/group at the same level.  If this is the first record/group, 
    <tt>order</tt> defaults to <tt>1</tt>.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>minOccurs</tt></td>
  <td>The minimum number of occurences of this record within its parent group or stream.
    Defaults to 1.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>maxOccurs</tt></td>
  <td>The maximum number of occurrences of this record within its parent group or stream.
    Defaults to <tt>unbounded</tt>.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>minLength</tt></td>
  <td>If the stream format is <tt>delimited</tt> or <tt>csv</tt>, <tt>minLength</tt> is the minimum number
    of fields required by this record.  Defaults to the number of fields defined for the record.
    <p>If the stream format is <tt>fixedlength</tt>, <tt>minLength</tt> is the minimum number 
    of characters required by this record.  Defaults to the sum of all field lengths definied for
    the record.</p>
    </td>
  <td>No</td>
  <td>csv, delimited, fixedlength</td>
</tr>
<tr>
  <td><tt>maxLength</tt></td>
  <td>If the stream format is <tt>delimited</tt> or <tt>csv</tt>, <tt>maxLength</tt> is the maximum number
    of fields allowed by this record.  Defaults to the number of fields defined for the record, or
    if no fields are declared, then unbounded.
    <p>If the stream format is <tt>fixedlength</tt>, <tt>maxLength</tt> is the maximum number 
    of characters allowed by this record.  Defaults to the sum of all field lengths defined for
    the record, or if no fields are declared, then unbounded.</p>
    </td>
  <td>No</td>
  <td>csv, delimited, fixedlength</td>
</tr>
<tr>
  <td><tt>class</tt></td>
  <td>The fully qualified class name of the bean object mapped to this record.  If not set,
    a <tt>BeanReader</tt> will fully validate the record, but no bean object will be returned
    and the reader will continue reading the next record.  If set to <tt>map</tt> or 
    any <tt>java.util.Map</tt> implementation, a Map object will be used with field names
    for keys and field values for values.
  </td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>template</tt></td>
  <td>The name of the template to include.  Children of this record
    are added after all properties included from the template.
  </td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>xmlName</tt></td>
  <td>The local name of the XML element mapped to this record.  Defaults to the record name.</td>
  <td>No</td>
  <td>xml</td>
</tr>
<tr>
  <td><tt>xmlNamespace</tt></td>
  <td>The namespace of the XML element mapped to this record.  Defaults to the namespace declared for
    this record's parent group or stream.</td>
  <td>No</td>
  <td>xml</td>
</tr>
<tr>
  <td><tt>xmlPrefix</tt></td>
  <td>The namespace prefix assigned to the declared <tt>xmlNamespace</tt> for marshalling XML.  
    If not specified, the default namespace (i.e. <tt>xmlns="..."</tt>) is used.</td>
  <td>No</td>
  <td>xml</td>
</tr>
</table>

<p>Children: 
( <a href="#field"><tt>field</tt></a> | 
<a href="#property"><tt>property</tt></a> |
<a href="#bean"><tt>bean</tt></a> |
<a href="#include"><tt>include</tt></a> )*
</p>


<h2><a name="bean">A.12. <tt>bean</tt></a></h2>
<p>A <tt>bean</tt> element is used to map fields and other bean objects to a parent bean or record.</p> 
<p>Attributes:</p>
<table>
<tr>
  <th>Attribute</th>
  <th>Description</th>
  <th>Required</th>
  <th>Format(s)</th>
</tr>
<tr>
  <td><tt>name</tt></td>
  <td>The name of the bean.  Unless a getter and/or setter is defined, the bean name is used
    for getting and setting the bean from its parent bean object.</td>
  <td>Yes</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>getter</tt></td>
  <td>The getter method used to retrieve the bean property value from the bean class of
    it's parent.  By default, the getter method is determined through intropection using
    the bean name.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>setter</tt></td>
  <td>The setter method used to set the bean property value on the bean class of
    it's parent.  By default, the setter method is determined through intropection using
    the bean name.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>class</tt></td>
  <td>The fully qualified class name of the object mapped to this bean. 
    If set to <tt>map</tt> or any <tt>java.util.Map</tt> implementation, a Map object will 
    be used with field/bean names for keys and field/bean values for values.
  </td>
  <td>Yes</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>template</tt></td>
  <td>The name of the template to include.  Children of this bean
    are added after all properties included from the template.
  </td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>collection</tt></td>
  <td>If the parent bean property type of this bean is a collection, <tt>collection</tt>
    is the fully qualified collection class name or collection type alias of it's parent bean
    property type, and <tt>type</tt> becomes the property type of the collection item.  
    May be set to <tt>array</tt> if the collection type is a Java array.
    <p>BeanIO will not derrive the collection type from it's parent bean object, thus 
    collection type beans must always be explicitly declared.</p>
    <p>There are a few restrictions specific to beans in any "flat" format (delimited, CSV or fixedlength):</p>
    <ul>
    <li>Collection bean values must appear in the stream consecutively.</li>
    <li>A collection type bean cannot contain collection children (fields or other beans) where
      the length is indeterminate (i.e. where <tt>minOccurs</tt> does not match <tt>maxOccurs</tt>).</li>
    <li>Bean collections must fully declare all child fields- there can be no gaps in the definition.
      (However, you can still skip over unwanted values using the <tt>ignore</tt> field attribute.)</li>
    </ul>
  </td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>minOccurs</tt></td>
  <td>The minimum consecutive occurrences of this bean.  
    <p>For CSV, delimited and fixed length streams, <tt>minOccurs</tt> defaults to 1, and should only
    be overridden for collection type beans.</p> 
    <p>For XML streams, <tt>minOccurs</tt> defaults to 1 if <tt>nillable</tt> is true, or
     0 otherwise.  <tt>minOccurs</tt> controls whether an element is marshalled for a null bean object
     or required during unmarshalling.</p>
    <p>During unmarshalling, if the configured minimum occurrences is not met, 
      an <tt>InvalidRecordException</tt> is thrown.</p>
  </td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>maxOccurs</tt></td>
  <td>The maximum consecutive occurrences of this bean.  By default, 
    <tt>maxOccurs</tt> is set to <tt>minOccurs</tt> or 1, whichever is greater.  If overridden for
    a CSV, delimited or fixed length stream, the value can only exceed <tt>minOccurs</tt> if the bean 
    appears at the end of a record.  If there is no limit to the number of occurrences, the value may 
    be set to <tt>unbounded</tt>.
    <p>Maximum occurrences is not used for validation.  When bounded, the
      size of a bean collection will not exceed the configured value, and additional occurrences
      are ignored.</p>
  </td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>xmlType</tt></td>
  <td>The XML node type mapped to this bean.  
  If not specified or set to <tt>element</tt>, this bean is mapped to an XML element.  If set to 
  <tt>none</tt>, fields and nested beans belonging to this bean are expected to be contained by
  this bean's parent record or bean.</td>
  <td>No</td>
  <td>xml</td>
</tr>
<tr>
  <td><tt>xmlName</tt></td>
  <td>The local name of the XML element mapped to this bean.  Defaults to the bean name.</td>
  <td>No</td>
  <td>xml</td>
</tr>
<tr>
  <td><tt>xmlNamespace</tt></td>
  <td>The namespace of the XML element mapped to this bean.  Defaults to the namespace declared for the
    parent record or bean definition.</td>
  <td>No</td>
  <td>xml</td>
</tr>
<tr>
  <td><tt>xmlPrefix</tt></td>
  <td>The namespace prefix assigned to the declared <tt>xmlNamespace</tt> for marshalling XML.  
    If not specified, the default namespace (i.e. <tt>xmlns="..."</tt>) is used.</td>
  <td>No</td>
  <td>xml</td>
</tr>
<tr>
  <td><tt>xmlWrapper</tt></td>
  <td>The local name of the XML element that wraps this bean element.  The
    XML wrapper element uses the same namespace of the element it wraps.  If a bean object
    is null when marshalled, <tt>minOccurs</tt> also controls whether the wrapper element 
    is marshalled.  By default, elements are not wrapped.</td>
  <td>No</td>
  <td>xml</td>
</tr>
<tr>
  <td><tt>nillable</tt></td>
  <td>Set to <tt>true</tt> if the W3C Schema Instance attribute <tt>nil</tt> should be
    set to true when the marshalled bean object is null.  Defaults to <tt>false</tt>.
    Nillable collection type beans that use a wrapper element will have the <tt>nil</tt> attribute set on the wrapping
    element when the bean collection value is null or empty.</td>
  <td>No</td>
  <td>xml</td>
</tr>
</table>

<p>Children: 
( <a href="#field"><tt>field</tt></a> |
<a href="#property"><tt>property</tt></a > |
<a href="#bean"><tt>bean</tt></a> |
<a href="#include"><tt>include</tt></a> )*
</p>


<h2><a name="field">A.13. <tt>field</tt></a></h2>
<p>A <tt>field</tt> element is used to define and map a field from a record to a bean property
and vice versa.</p> 
<p>Attributes:</p>
<table>
<tr>
  <th>Attribute</th>
  <th>Description</th>
  <th>Required</th>
  <th>Formats</th>
</tr>
<tr>
  <td><tt>name</tt></td>
  <td>The name of field.  Unless a getter and/or setter is defined, the field name is used
    for the bean property name.</td>
  <td>Yes</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>getter</tt></td>
  <td>The getter method used to retrieve the field property value from the bean class of
    the record.  By default, the getter method is determined through intropection using
    the field name.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>setter</tt></td>
  <td>The setter method used to set the field property value on the bean class of
    the record.  By default, the setter method is determined through intropection using
    the field name.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>rid</tt></td>
  <td>Record identifier indicator.  Set to <tt>true</tt> if this field is used to identify the record.  
    More than one field can be used to identify a record.  Defaults to <tt>false</tt>.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>position</tt></td>
  <td>For delimited and CSV formatted streams, <tt>position</tt> is the index of the field
    within the record, beginning at 0.  And for fixed length formatted streams, <tt>position</tt>
    is the index of the first character of the field within the record, beginning at 0.
    <p>
    If the field is a collection, or the field is a property of a bean that is a collection, 
    <tt>position</tt> should be set based on the first occurrence of the field in a record.
    </p>
    <p>
    A position must be specified for all fields in a record, or for none at all.  If positions
    are not specified, BeanIO will automatically calculate field positions based on the order
    in which the fields are defined in the mapping file.
    </p>
  </td>
  <td>No</td>
  <td>csv, delimited, fixedlength</td>
</tr>
<tr>
  <td><tt>trim</tt></td>
  <td>Set to <tt>true</tt> to trim the field text before validation and type
    conversion.  Defaults to <tt>false</tt>.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>required</tt></td>
  <td>Set to <tt>true</tt> if this this field is required.  If this field is required,
    and its field text is empty or the field is not present in the record, a <tt>BeanReader</tt> 
    will throw an exception when reading the record.  Defaults to <tt>false</tt>.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>minLength</tt></td>
  <td>The minimum length of the field text before type conversion.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>maxLength</tt></td>
  <td>The maximum length of the field text before type conversion.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>regex</tt></td>
  <td>The regular expression pattern the field text must match.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>literal</tt></td>
  <td>Sets the <i>literal</i> or constant value of this field.  When reading an input stream,
    a <tt>BeanReader</tt> will throw an exception if the field text does not match the
    literal value.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>default</tt></td>
  <td>The default value of this field.
    <p>When unmarshalling a stream, this value is set on the bean object when the
    field text is null or the empty string.  And when marshalling, the
    default value is used when the property value is null or ignore is set to 
    <tt>true</tt> (unless disabled).</p>
    <p>The default value is converted to a Java object using the same type 
    handler configured for this field.</p></td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>type</tt></td>
  <td>The fully qualified class name or type alias of the field value.  By default,
    BeanIO will derrive the field type from the bean class of the record.  This attribute
    can be used to override the default or may be required if the bean class of the
    record is a <tt>Map</tt>.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>collection</tt></td>
  <td>If the bean property type of this field is a collection, <tt>collection</tt>
    is the fully qualified collection class name or collection type alias of the bean
    property type, and <tt>type</tt> becomes the property type of the collection item.  
    May be set to <tt>array</tt> if the collection type is a Java array.
    <p>BeanIO will not derrive the collection type from the record bean object, thus 
    collection type fields must always be explicitly declared.</p>
  </td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>minOccurs</tt></td>
  <td>The minimum consecutive occurrences of this field in a record.
    <p>For CSV, delimited and fixed length streams, <tt>minOccurs</tt> defaults to 1, and should only
     be overridden for collection type fields.</p> 
    <p>For XML streams, <tt>minOccurs</tt> defaults to 1 if <tt>nillable</tt> is true, or
     0 otherwise.  <tt>minOccurs</tt> controls whether an element is marshalled for a null field object
     or required during unmarshalling.</p>
    <p>During unmarshalling, if the configured minimum occurrences is not met, 
      an <tt>InvalidRecordException</tt> is thrown.</p>
  </td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>maxOccurs</tt></td>
  <td>The maximum consecutive occurrences of this field in a record.  By default, 
    <tt>maxOccurs</tt> is set to <tt>minOccurs</tt> or 1, whichever is greater.  If overridden
    for a non-XML stream format, the value can only exceed <tt>minOccurs</tt> if this is the last field
    in the record.  The value may be set to <tt>unbounded</tt> if there is no limit to the 
    number of occurrences of this field.
    <p>Maximum occurrences is not used for validation. When bounded, the size of a 
    collection will not exceed the configured value, and additional occurrences are ignored.</p>
  </td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>format</tt></td>
  <td>The decimal format pattern for <tt>Number</tt> field properties, or the simple
    date format pattern for <tt>Date</tt> field properties.
    <p>The <tt>format</tt> value can accessed by any custom type handler that
    implements <tt>ConfigurableTypeHandler</tt>.</p>  
  </td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>typeHandler</tt></td>
  <td>The name of the type handler to use for type conversion.  By default, BeanIO
    will select a type handler based on the field type when set, or through 
    introspection of this field's parent record or bean class.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>ignore</tt></td>
  <td>Set to <tt>true</tt> if this field is not a property of the record bean class.  
    Defaults to <tt>false</tt>.</td>
  <td>No</td>
  <td>*</td>
</tr>
<tr>
  <td><tt>length</tt></td>
  <td>The padded length of this field measured in characters.  Length is required for fixed
    length formatted streams, and can be set for fields in other stream formats (along with
    a padding character) to enable field padding.</td>
  <td>Yes<sup>1</sup></td>
  <td><tt>*</tt></td>
</tr>
<tr>
  <td><tt>padding</tt></td>
  <td>The character used to pad this field.  For fixed length formatted streams,
    <tt>padding</tt> defaults to a space.  For non-fixed length formatted streams,
    padding is disabled unless a padding character and length is specified.
    
    <p>If padding is enabled, the <tt>required</tt> field attribute has some control over the
    marshalling and unmarshalling of null values.</p>
    
    <p>When unmarshalling a field consisting of all spaces in a fixed length stream, 
    if <tt>required</tt> is false, the field
    is accepted regardless of the padding character.  If
    <tt>required</tt> is true, a required field validation error is triggered.  And when
    marshalling a null field value, if <tt>required</tt> is false, 
    the field text is formatted as spaces regardless of the configured padding character.
    </p>
    
    <p>In other stream formats that are not fixed length, null field values are 
    unmarshalled and marshalled as empty strings when <tt>required</tt> is false.
    When <tt>required</tt> is true, unmarshalling an empty string will trigger a required
    field validation error, and marshalling a null value will fill the field text with
    the padding character up to the padded length of the field.</p>
  </td>
  <td>No</td>
  <td><tt>*</tt></td>
</tr>
<tr>
  <td><tt>justify</tt></td>
  <td>The justification of the field text within this padded field.  Either
    <tt>left</tt> or <tt>right</tt>.  Defaults to <tt>left</tt>.</td>
  <td>No</td>
  <td><tt>*</tt></td>
</tr>
<tr>
  <td><tt>xmlType</tt></td>
  <td>The XML node type mapped to this field.  The type can be set to <tt>element</tt> (default)
  to map this field to an XML element, <tt>attribute</tt> to map to an XML attribute, or <tt>text</tt>
  to map the field value to the enclosed text of the parent record or bean element.  May also be
  set to <tt>none</tt> if a default value is provided.
  
  <p>When set to <tt>text</tt>, <tt>xmlName</tt> and <tt>xmlNamespace</tt> have no effect.</p></td>
  <td>No</td>
  <td>xml</td>
</tr>
<tr>
  <td><tt>xmlName</tt></td>
  <td>The local name of the XML element or attribute mapped to this field.  Defaults to the field name.</td>
  <td>No</td>
  <td>xml</td>
</tr>
<tr>
  <td><tt>xmlNamespace</tt></td>
  <td>The namespace of the XML element mapped to this field.  Defaults to the namespace configured for the
    parent record or bean definition.</td>
  <td>No</td>
  <td>xml</td>
</tr>
<tr>
  <td><tt>xmlPrefix</tt></td>
  <td>The namespace prefix assigned to the configured <tt>xmlNamespace</tt> for marshalling XML.  
    If not specified, the default namespace (i.e. <tt>xmlns="..."</tt>) is used.</td>
  <td>No</td>
  <td>xml</td>
</tr>
<tr>
  <td><tt>xmlWrapper</tt></td>
  <td>The local name of the XML element that wraps this field.  The
    XML wrapper element uses the same namespace configured for the field it wraps.  If a field value
    is null when marshalled, <tt>minOccurs</tt> also controls whether the wrapper element 
    is marshalled.  By default, fields are not wrapped.</td>
  <td>No</td>
  <td>xml</td>
</tr>
<tr>
  <td><tt>nillable</tt></td>
  <td>Set to <tt>true</tt> if the W3C Schema Instance attribute <tt>nil</tt> should be
    set to true when the marshalled field value is null.  Defaults to <tt>false</tt>.  Nillable collection
    type fields that use a wrapper element will have the <tt>nil</tt> attribute set on the wrapping
    element when the field collection value is null or empty. </td>
  <td>No</td>
  <td>xml</td>
</tr>
</table>
<p><sup>1</sup>Only required for fixed length fields.  If a literal value is supplied for 
a fixed length field, <tt>length</tt> will default to the length of the literal value.</p> 


<h1><a name="B">Appendix B: Error Message Parameters</a></h1>

<p>The following table shows the message parameters used to format an error
message for each configurable validation rule.</p>

<table style="vertical-align: top">
<tr>
  <th>Type</th>
  <th>Rule Name</th>
  <th>Index</th>
  <th>Value</th>
</tr>
<tr>
  <td rowspan="12">Record Error</td>
  <td><tt>malformed</tt></td>
  <td>0</td>
  <td>Line Number</td>
</tr>
<tr>
  <td><tt>unidentified</tt></td>
  <td>0</td>
  <td>Line Number</td>
</tr>
<tr>
  <td rowspan="2"><tt>unexpected</tt></td>
  <td>0</td>
  <td>Line Number</td>
</tr>
<tr>
  <td>1</td>
  <td>Record Label/Name</td>
</tr>
<tr>
  <td rowspan="4"><tt>minLength</tt></td>
  <td>0</td>
  <td>Line Number</td>
</tr>
<tr>
  <td>1</td>
  <td>Record Label/Name</td>
</tr>
<tr>
  <td>2</td>
  <td>Minimum Length</td>
</tr>
<tr>
  <td>3</td>
  <td>Maximum Length</td>
</tr>
<tr>
  <td rowspan="4"><tt>maxLength</tt></td>
  <td>0</td>
  <td>Line Number</td>
</tr>
<tr>
  <td>1</td>
  <td>Record Label/Name</td>
</tr>
<tr>
  <td>2</td>
  <td>Minimum Length</td>
</tr>
<tr>
  <td>3</td>
  <td>Maximum Length</td>
</tr>
<tr>
  <td rowspan="52">Field Error</td>
  <td rowspan="4"><tt>required</tt></td>
  <td>0</td>
  <td>Line Number</td>
</tr>
<tr>
  <td>1</td>
  <td>Record Label/Name</td>
</tr>
<tr>
  <td>2</td>
  <td>Field Label/Name</td>
</tr>
<tr>
  <td>3</td>
  <td>Field Text</td>
</tr>
<tr>
  <td rowspan="4"><tt>nillable</tt></td>
  <td>0</td>
  <td>Line Number</td>
</tr>
<tr>
  <td>1</td>
  <td>Record Label/Name</td>
</tr>
<tr>
  <td>2</td>
  <td>Field Label/Name</td>
</tr>
<tr>
  <td>3</td>
  <td>Field Text</td>
</tr>
<tr>
  <td rowspan="6"><tt>minLength</tt></td>
  <td>0</td>
  <td>Line Number</td>
</tr>
<tr>
  <td>1</td>
  <td>Record Label/Name</td>
</tr>
<tr>
  <td>2</td>
  <td>Field Label/Name</td>
</tr>
<tr>
  <td>3</td>
  <td>Field Text</td>
</tr>
<tr>
  <td>4</td>
  <td>Minimum Length</td>
</tr>
<tr>
  <td>5</td>
  <td>Maximum Length</td>
</tr>
<tr>
  <td rowspan="6"><tt>maxLength</tt></td>
  <td>0</td>
  <td>Line Number</td>
</tr>
<tr>
  <td>1</td>
  <td>Record Label/Name</td>
</tr>
<tr>
  <td>2</td>
  <td>Field Label/Name</td>
</tr>
<tr>
  <td>3</td>
  <td>Field Text</td>
</tr>
<tr>
  <td>4</td>
  <td>Minimum Length</td>
</tr>
<tr>
  <td>5</td>
  <td>Maximum Length</td>
</tr>
<tr>
  <td rowspan="5"><tt>length</tt></td>
  <td>0</td>
  <td>Line Number</td>
</tr>
<tr>
  <td>1</td>
  <td>Record Label/Name</td>
</tr>
<tr>
  <td>2</td>
  <td>Field Label/Name</td>
</tr>
<tr>
  <td>3</td>
  <td>Field Text</td>
</tr>
<tr>
  <td>4</td>
  <td>Fixed Length Field Length</td>
</tr>
<tr>
  <td rowspan="5"><tt>regex</tt></td>
  <td>0</td>
  <td>Line Number</td>
</tr>
<tr>
  <td>1</td>
  <td>Record Label/Name</td>
</tr>
<tr>
  <td>2</td>
  <td>Field Label/Name</td>
</tr>
<tr>
  <td>3</td>
  <td>Field Text</td>
</tr>
<tr>
  <td>4</td>
  <td>Regular Expression Pattern</td>
</tr>
<tr>
  <td rowspan="5"><tt>type</tt></td>
  <td>0</td>
  <td>Line Number</td>
</tr>
<tr>
  <td>1</td>
  <td>Record Label/Name</td>
</tr>
<tr>
  <td>2</td>
  <td>Field Label/Name</td>
</tr>
<tr>
  <td>3</td>
  <td>Field Text</td>
</tr>
<tr>
  <td>4</td>
  <td><tt>TypeConversionException</tt> error message.</td>
</tr>
<tr>
  <td rowspan="5"><tt>literal</tt></td>
  <td>0</td>
  <td>Line Number</td>
</tr>
<tr>
  <td>1</td>
  <td>Record Label/Name</td>
</tr>
<tr>
  <td>2</td>
  <td>Field Label/Name</td>
</tr>
<tr>
  <td>3</td>
  <td>Field Text</td>
</tr>
<tr>
  <td>4</td>
  <td>Literal value</td>
</tr>
<tr>
  <td rowspan="6"><tt>minOccurs</tt></td>
  <td>0</td>
  <td>Line Number</td>
</tr>
<tr>
  <td>1</td>
  <td>Record Label/Name</td>
</tr>
<tr>
  <td>2</td>
  <td>Field or Bean Label/Name</td>
</tr>
<tr>
  <td>3</td>
  <td>-</td>
</tr>
<tr>
  <td>4</td>
  <td>Minimum occurrences</td>
</tr>
<tr>
  <td>5</td>
  <td>Maximum occurences</td>
</tr>
<tr>
  <td rowspan="6"><tt>maxOccurs</tt></td>
  <td>0</td>
  <td>Line Number</td>
</tr>
<tr>
  <td>1</td>
  <td>Record Label/Name</td>
</tr>
<tr>
  <td>2</td>
  <td>Field or Bean Label/Name</td>
</tr>
<tr>
  <td>3</td>
  <td>-</td>
</tr>
<tr>
  <td>4</td>
  <td>Minimum occurrences</td>
</tr>
<tr>
  <td>5</td>
  <td>Maximum occurences</td>
</tr>
</table>

<br />
<br />
<br />

</body>
</html>